kubernetes-handbook/develop/client-go-informer-sourceco...

6042 lines
452 KiB
HTML
Raw Normal View History

<!DOCTYPE HTML>
<html lang="zh-hans" >
<head>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>client-go 中的 informer 源码分析 · Kubernetes Handbook - Kubernetes 中文指南/云原生应用架构实践手册 · Jimmy Song</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="">
<meta name="generator" content="GitBook 3.2.3">
<meta name="author" content="Jimmy Song宋净超">
<link rel="stylesheet" href="../gitbook/style.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-splitter/splitter.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-page-toc-button/plugin.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-image-captions/image-captions.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-back-to-top-button/plugin.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-search-plus/search.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-tbfed-pagefooter/footer.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-prism/prism-ghcolors.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-lightbox/css/lightbox.min.css">
<link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
<meta name="HandheldFriendly" content="true"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
<link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">
<link rel="next" href="operator.html" />
<link rel="prev" href="client-go-sample.html" />
<link rel="shortcut icon" href='../favicon.ico' type="image/x-icon">
<link rel="bookmark" href='../favicon.ico' type="image/x-icon">
<style>
@media only screen and (max-width: 640px) {
.book-header .hidden-mobile {
display: none;
}
}
</style>
<script>
window["gitbook-plugin-github-buttons"] = {"repo":"rootsongjc/kubernetes-handbook","types":["star"],"size":"small"};
</script>
</head>
<body>
<div class="book">
<div class="book-summary">
<div id="book-search-input" role="search">
<input type="text" placeholder="输入并搜索" />
</div>
<nav role="navigation">
<ul class="summary">
<li>
<a href="https://jimmysong.io" target="_blank" class="custom-link">回到主页</a>
</li>
<li>
<a href="https://jimmysong.io/awesome-cloud-native" target="_blank" class="custom-link">云原生开源项目大全</a>
</li>
<li>
<a href="https://cloudnative.to" target="_blank" class="custom-link">云原生社区</a>
</li>
<li class="divider"></li>
<li class="header">前言</li>
<li class="chapter " data-level="1.1" data-path="../">
<a href="../">
<b>1.1.</b>
序言
</a>
</li>
<li class="header">云原生</li>
<li class="chapter " data-level="2.1" data-path="../cloud-native/cloud-native-definition.html">
<a href="../cloud-native/cloud-native-definition.html">
<b>2.1.</b>
云原生Cloud Native的定义
</a>
</li>
<li class="chapter " data-level="2.2" data-path="../cloud-native/cloud-native-philosophy.html">
<a href="../cloud-native/cloud-native-philosophy.html">
<b>2.2.</b>
云原生的设计哲学
</a>
</li>
<li class="chapter " data-level="2.3" data-path="../cloud-native/kubernetes-history.html">
<a href="../cloud-native/kubernetes-history.html">
<b>2.3.</b>
Kubernetes 的诞生
</a>
</li>
<li class="chapter " data-level="2.4" data-path="../cloud-native/kubernetes-and-cloud-native-app-overview.html">
<a href="../cloud-native/kubernetes-and-cloud-native-app-overview.html">
<b>2.4.</b>
Kubernetes 与云原生应用概览
</a>
</li>
<li class="chapter " data-level="2.5" data-path="../cloud-native/from-kubernetes-to-cloud-native.html">
<a href="../cloud-native/from-kubernetes-to-cloud-native.html">
<b>2.5.</b>
云原生应用之路 —— 从 Kubernetes 到云原生
</a>
</li>
<li class="chapter " data-level="2.6" data-path="../cloud-native/define-cloud-native-app.html">
<a href="../cloud-native/define-cloud-native-app.html">
<b>2.6.</b>
定义云原生应用
</a>
<ul class="articles">
<li class="chapter " data-level="2.6.1" data-path="../cloud-native/oam.html">
<a href="../cloud-native/oam.html">
<b>2.6.1.</b>
OAM
</a>
<ul class="articles">
<li class="chapter " data-level="2.6.1.1" data-path="../cloud-native/workload.html">
<a href="../cloud-native/workload.html">
<b>2.6.1.1.</b>
Workload
</a>
</li>
<li class="chapter " data-level="2.6.1.2" data-path="../cloud-native/component.html">
<a href="../cloud-native/component.html">
<b>2.6.1.2.</b>
Component
</a>
</li>
<li class="chapter " data-level="2.6.1.3" data-path="../cloud-native/trait.html">
<a href="../cloud-native/trait.html">
<b>2.6.1.3.</b>
Trait
</a>
</li>
<li class="chapter " data-level="2.6.1.4" data-path="../cloud-native/application-scope.html">
<a href="../cloud-native/application-scope.html">
<b>2.6.1.4.</b>
Application Scope
</a>
</li>
<li class="chapter " data-level="2.6.1.5" data-path="../cloud-native/application-configuration.html">
<a href="../cloud-native/application-configuration.html">
<b>2.6.1.5.</b>
Application Configuration
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="2.6.2" data-path="../cloud-native/crossplane.html">
<a href="../cloud-native/crossplane.html">
<b>2.6.2.</b>
Crossplane
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="2.7" data-path="../cloud-native/cloud-native-programming-languages.html">
<a href="../cloud-native/cloud-native-programming-languages.html">
<b>2.7.</b>
云原生编程语言
</a>
<ul class="articles">
<li class="chapter " data-level="2.7.1" data-path="../cloud-native/cloud-native-programming-language-ballerina.html">
<a href="../cloud-native/cloud-native-programming-language-ballerina.html">
<b>2.7.1.</b>
云原生编程语言 Ballerina
</a>
</li>
<li class="chapter " data-level="2.7.2" data-path="../cloud-native/cloud-native-programming-language-pulumi.html">
<a href="../cloud-native/cloud-native-programming-language-pulumi.html">
<b>2.7.2.</b>
云原生编程语言 Pulumi
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="2.8" data-path="../cloud-native/the-future-of-cloud-native.html">
<a href="../cloud-native/the-future-of-cloud-native.html">
<b>2.8.</b>
云原生的未来
</a>
</li>
<li class="header">快速入门</li>
<li class="chapter " data-level="3.1" data-path="../cloud-native/quick-start.html">
<a href="../cloud-native/quick-start.html">
<b>3.1.</b>
云原生新手入门指南
</a>
</li>
<li class="chapter " data-level="3.2" data-path="../cloud-native/play-with-kubernetes.html">
<a href="../cloud-native/play-with-kubernetes.html">
<b>3.2.</b>
Play with Kubernetes
</a>
</li>
<li class="chapter " data-level="3.3" data-path="../cloud-native/cloud-native-local-quick-start.html">
<a href="../cloud-native/cloud-native-local-quick-start.html">
<b>3.3.</b>
快速部署一个云原生本地实验环境
</a>
</li>
<li class="chapter " data-level="3.4" data-path="../cloud-native/setup-kubernetes-with-rancher-and-aliyun.html">
<a href="../cloud-native/setup-kubernetes-with-rancher-and-aliyun.html">
<b>3.4.</b>
使用 Rancher 在阿里云上部署 Kubenretes 集群
</a>
</li>
<li class="header">概念与原理</li>
<li class="chapter " data-level="4.1" data-path="../concepts/">
<a href="../concepts/">
<b>4.1.</b>
Kubernetes 架构
</a>
<ul class="articles">
<li class="chapter " data-level="4.1.1" data-path="../concepts/concepts.html">
<a href="../concepts/concepts.html">
<b>4.1.1.</b>
设计理念
</a>
</li>
<li class="chapter " data-level="4.1.2" data-path="../concepts/etcd.html">
<a href="../concepts/etcd.html">
<b>4.1.2.</b>
Etcd 解析
</a>
</li>
<li class="chapter " data-level="4.1.3" data-path="../concepts/open-interfaces.html">
<a href="../concepts/open-interfaces.html">
<b>4.1.3.</b>
开放接口
</a>
<ul class="articles">
<li class="chapter " data-level="4.1.3.1" data-path="../concepts/cri.html">
<a href="../concepts/cri.html">
<b>4.1.3.1.</b>
CRI - Container Runtime Interface容器运行时接口
</a>
</li>
<li class="chapter " data-level="4.1.3.2" data-path="../concepts/cni.html">
<a href="../concepts/cni.html">
<b>4.1.3.2.</b>
CNI - Container Network Interface容器网络接口
</a>
</li>
<li class="chapter " data-level="4.1.3.3" data-path="../concepts/csi.html">
<a href="../concepts/csi.html">
<b>4.1.3.3.</b>
CSI - Container Storage Interface容器存储接口
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.1.4" data-path="../concepts/objects.html">
<a href="../concepts/objects.html">
<b>4.1.4.</b>
资源对象与基本概念解析
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.2" data-path="../concepts/pod-state-and-lifecycle.html">
<a href="../concepts/pod-state-and-lifecycle.html">
<b>4.2.</b>
Pod 状态与生命周期管理
</a>
<ul class="articles">
<li class="chapter " data-level="4.2.1" data-path="../concepts/pod-overview.html">
<a href="../concepts/pod-overview.html">
<b>4.2.1.</b>
Pod 概览
</a>
</li>
<li class="chapter " data-level="4.2.2" data-path="../concepts/pod.html">
<a href="../concepts/pod.html">
<b>4.2.2.</b>
Pod 解析
</a>
</li>
<li class="chapter " data-level="4.2.3" data-path="../concepts/init-containers.html">
<a href="../concepts/init-containers.html">
<b>4.2.3.</b>
Init 容器
</a>
</li>
<li class="chapter " data-level="4.2.4" data-path="../concepts/pause-container.html">
<a href="../concepts/pause-container.html">
<b>4.2.4.</b>
Pause 容器
</a>
</li>
<li class="chapter " data-level="4.2.5" data-path="../concepts/pod-security-policy.html">
<a href="../concepts/pod-security-policy.html">
<b>4.2.5.</b>
Pod 安全策略
</a>
</li>
<li class="chapter " data-level="4.2.6" data-path="../concepts/pod-lifecycle.html">
<a href="../concepts/pod-lifecycle.html">
<b>4.2.6.</b>
Pod 的生命周期
</a>
</li>
<li class="chapter " data-level="4.2.7" data-path="../concepts/pod-hook.html">
<a href="../concepts/pod-hook.html">
<b>4.2.7.</b>
Pod Hook
</a>
</li>
<li class="chapter " data-level="4.2.8" data-path="../concepts/pod-preset.html">
<a href="../concepts/pod-preset.html">
<b>4.2.8.</b>
Pod Preset
</a>
</li>
<li class="chapter " data-level="4.2.9" data-path="../concepts/pod-disruption-budget.html">
<a href="../concepts/pod-disruption-budget.html">
<b>4.2.9.</b>
Pod 中断与 PDBPod 中断预算)
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.3" data-path="../concepts/cluster.html">
<a href="../concepts/cluster.html">
<b>4.3.</b>
集群资源管理
</a>
<ul class="articles">
<li class="chapter " data-level="4.3.1" data-path="../concepts/node.html">
<a href="../concepts/node.html">
<b>4.3.1.</b>
Node
</a>
</li>
<li class="chapter " data-level="4.3.2" data-path="../concepts/namespace.html">
<a href="../concepts/namespace.html">
<b>4.3.2.</b>
Namespace
</a>
</li>
<li class="chapter " data-level="4.3.3" data-path="../concepts/label.html">
<a href="../concepts/label.html">
<b>4.3.3.</b>
Label
</a>
</li>
<li class="chapter " data-level="4.3.4" data-path="../concepts/annotation.html">
<a href="../concepts/annotation.html">
<b>4.3.4.</b>
Annotation
</a>
</li>
<li class="chapter " data-level="4.3.5" data-path="../concepts/taint-and-toleration.html">
<a href="../concepts/taint-and-toleration.html">
<b>4.3.5.</b>
Taint 和 Toleration污点和容忍
</a>
</li>
<li class="chapter " data-level="4.3.6" data-path="../concepts/garbage-collection.html">
<a href="../concepts/garbage-collection.html">
<b>4.3.6.</b>
垃圾收集
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.4" data-path="../concepts/controllers.html">
<a href="../concepts/controllers.html">
<b>4.4.</b>
控制器
</a>
<ul class="articles">
<li class="chapter " data-level="4.4.1" data-path="../concepts/deployment.html">
<a href="../concepts/deployment.html">
<b>4.4.1.</b>
Deployment
</a>
</li>
<li class="chapter " data-level="4.4.2" data-path="../concepts/statefulset.html">
<a href="../concepts/statefulset.html">
<b>4.4.2.</b>
StatefulSet
</a>
</li>
<li class="chapter " data-level="4.4.3" data-path="../concepts/daemonset.html">
<a href="../concepts/daemonset.html">
<b>4.4.3.</b>
DaemonSet
</a>
</li>
<li class="chapter " data-level="4.4.4" data-path="../concepts/replicaset.html">
<a href="../concepts/replicaset.html">
<b>4.4.4.</b>
ReplicationController 和 ReplicaSet
</a>
</li>
<li class="chapter " data-level="4.4.5" data-path="../concepts/job.html">
<a href="../concepts/job.html">
<b>4.4.5.</b>
Job
</a>
</li>
<li class="chapter " data-level="4.4.6" data-path="../concepts/cronjob.html">
<a href="../concepts/cronjob.html">
<b>4.4.6.</b>
CronJob
</a>
</li>
<li class="chapter " data-level="4.4.7" data-path="../concepts/horizontal-pod-autoscaling.html">
<a href="../concepts/horizontal-pod-autoscaling.html">
<b>4.4.7.</b>
Horizontal Pod Autoscaling
</a>
<ul class="articles">
<li class="chapter " data-level="4.4.7.1" data-path="../concepts/custom-metrics-hpa.html">
<a href="../concepts/custom-metrics-hpa.html">
<b>4.4.7.1.</b>
自定义指标 HPA
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.4.8" data-path="../concepts/admission-controller.html">
<a href="../concepts/admission-controller.html">
<b>4.4.8.</b>
准入控制器Admission Controller
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.5" data-path="../concepts/service-discovery.html">
<a href="../concepts/service-discovery.html">
<b>4.5.</b>
服务发现与路由
</a>
<ul class="articles">
<li class="chapter " data-level="4.5.1" data-path="../concepts/service.html">
<a href="../concepts/service.html">
<b>4.5.1.</b>
Service
</a>
</li>
<li class="chapter " data-level="4.5.2" data-path="../concepts/topology-aware-routing.html">
<a href="../concepts/topology-aware-routing.html">
<b>4.5.2.</b>
拓扑感知路由
</a>
</li>
<li class="chapter " data-level="4.5.3" data-path="../concepts/ingress.html">
<a href="../concepts/ingress.html">
<b>4.5.3.</b>
Ingress
</a>
<ul class="articles">
<li class="chapter " data-level="4.5.3.1" data-path="../concepts/traefik-ingress-controller.html">
<a href="../concepts/traefik-ingress-controller.html">
<b>4.5.3.1.</b>
Traefik Ingress Controller
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.5.4" data-path="../concepts/kubernetes-service-api.html">
<a href="../concepts/kubernetes-service-api.html">
<b>4.5.4.</b>
Kubernetes Service API
</a>
<ul class="articles">
<li class="chapter " data-level="4.5.4.1" data-path="../concepts/service-api-overview.html">
<a href="../concepts/service-api-overview.html">
<b>4.5.4.1.</b>
Service API 简介
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="4.6" data-path="../concepts/authentication-and-permission.html">
<a href="../concepts/authentication-and-permission.html">
<b>4.6.</b>
身份与权限控制
</a>
<ul class="articles">
<li class="chapter " data-level="4.6.1" data-path="../concepts/serviceaccount.html">
<a href="../concepts/serviceaccount.html">
<b>4.6.1.</b>
ServiceAccount
</a>
</li>
<li class="chapter " data-level="4.6.2" data-path="../concepts/rbac.html">
<a href="../concepts/rbac.html">
<b>4.6.2.</b>
基于角色的访问控制RBAC
</a>
</li>
<li class="chapter " data-level="4.6.3" data-path="../concepts/network-policy.html">
<a href="../concepts/network-policy.html">
<b>4.6.3.</b>
NetworkPolicy
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.7" data-path="../concepts/networking.html">
<a href="../concepts/networking.html">
<b>4.7.</b>
网络
</a>
<ul class="articles">
<li class="chapter " data-level="4.7.1" data-path="../concepts/flannel.html">
<a href="../concepts/flannel.html">
<b>4.7.1.</b>
Kubernetes 中的网络解析 —— 以 flannel 为例
</a>
</li>
<li class="chapter " data-level="4.7.2" data-path="../concepts/calico.html">
<a href="../concepts/calico.html">
<b>4.7.2.</b>
Kubernetes 中的网络解析 —— 以 calico 为例
</a>
</li>
<li class="chapter " data-level="4.7.3" data-path="../concepts/cilium.html">
<a href="../concepts/cilium.html">
<b>4.7.3.</b>
具备 API 感知的网络和安全性管理开源软件 Cilium
</a>
<ul class="articles">
<li class="chapter " data-level="4.7.3.1" data-path="../concepts/cilium-concepts.html">
<a href="../concepts/cilium-concepts.html">
<b>4.7.3.1.</b>
Cilium 架构设计与概念解析
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="4.8" data-path="../concepts/storage.html">
<a href="../concepts/storage.html">
<b>4.8.</b>
存储
</a>
<ul class="articles">
<li class="chapter " data-level="4.8.1" data-path="../concepts/secret.html">
<a href="../concepts/secret.html">
<b>4.8.1.</b>
Secret
</a>
</li>
<li class="chapter " data-level="4.8.2" data-path="../concepts/configmap.html">
<a href="../concepts/configmap.html">
<b>4.8.2.</b>
ConfigMap
</a>
<ul class="articles">
<li class="chapter " data-level="4.8.2.1" data-path="../concepts/configmap-hot-update.html">
<a href="../concepts/configmap-hot-update.html">
<b>4.8.2.1.</b>
ConfigMap 的热更新
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.8.3" data-path="../concepts/volume.html">
<a href="../concepts/volume.html">
<b>4.8.3.</b>
Volume
</a>
</li>
<li class="chapter " data-level="4.8.4" data-path="../concepts/persistent-volume.html">
<a href="../concepts/persistent-volume.html">
<b>4.8.4.</b>
持久化卷Persistent Volume
</a>
</li>
<li class="chapter " data-level="4.8.5" data-path="../concepts/storageclass.html">
<a href="../concepts/storageclass.html">
<b>4.8.5.</b>
Storage Class
</a>
</li>
<li class="chapter " data-level="4.8.6" data-path="../concepts/local-persistent-storage.html">
<a href="../concepts/local-persistent-storage.html">
<b>4.8.6.</b>
本地持久化存储
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.9" data-path="../concepts/extension.html">
<a href="../concepts/extension.html">
<b>4.9.</b>
集群扩展
</a>
<ul class="articles">
<li class="chapter " data-level="4.9.1" data-path="../concepts/custom-resource.html">
<a href="../concepts/custom-resource.html">
<b>4.9.1.</b>
使用自定义资源扩展 API
</a>
</li>
<li class="chapter " data-level="4.9.2" data-path="../concepts/crd.html">
<a href="../concepts/crd.html">
<b>4.9.2.</b>
使用 CRD 扩展 Kubernetes API
</a>
</li>
<li class="chapter " data-level="4.9.3" data-path="../concepts/aggregated-api-server.html">
<a href="../concepts/aggregated-api-server.html">
<b>4.9.3.</b>
Aggregated API Server
</a>
</li>
<li class="chapter " data-level="4.9.4" data-path="../concepts/apiservice.html">
<a href="../concepts/apiservice.html">
<b>4.9.4.</b>
APIService
</a>
</li>
<li class="chapter " data-level="4.9.5" data-path="../concepts/service-catalog.html">
<a href="../concepts/service-catalog.html">
<b>4.9.5.</b>
Service Catalog
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.10" data-path="../concepts/multicluster.html">
<a href="../concepts/multicluster.html">
<b>4.10.</b>
多集群管理
</a>
<ul class="articles">
<li class="chapter " data-level="4.10.1" data-path="../concepts/multi-cluster-services-api.html">
<a href="../concepts/multi-cluster-services-api.html">
<b>4.10.1.</b>
多集群服务 APIMulti-Cluster Services API
</a>
</li>
<li class="chapter " data-level="4.10.2" data-path="../practice/federation.html">
<a href="../practice/federation.html">
<b>4.10.2.</b>
集群联邦Cluster Federation
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="4.11" data-path="../concepts/scheduling.html">
<a href="../concepts/scheduling.html">
<b>4.11.</b>
资源调度
</a>
<ul class="articles">
<li class="chapter " data-level="4.11.1" data-path="../concepts/qos.html">
<a href="../concepts/qos.html">
<b>4.11.1.</b>
服务质量等级QoS
</a>
</li>
</ul>
</li>
<li class="header">用户指南</li>
<li class="chapter " data-level="5.1" data-path="../guide/">
<a href="../guide/">
<b>5.1.</b>
用户指南概览
</a>
</li>
<li class="chapter " data-level="5.2" data-path="../guide/resource-configuration.html">
<a href="../guide/resource-configuration.html">
<b>5.2.</b>
资源对象配置
</a>
<ul class="articles">
<li class="chapter " data-level="5.2.1" data-path="../guide/configure-liveness-readiness-probes.html">
<a href="../guide/configure-liveness-readiness-probes.html">
<b>5.2.1.</b>
配置 Pod 的 liveness 和 readiness 探针
</a>
</li>
<li class="chapter " data-level="5.2.2" data-path="../guide/configure-pod-service-account.html">
<a href="../guide/configure-pod-service-account.html">
<b>5.2.2.</b>
配置 Pod 的 Service Account
</a>
</li>
<li class="chapter " data-level="5.2.3" data-path="../guide/secret-configuration.html">
<a href="../guide/secret-configuration.html">
<b>5.2.3.</b>
Secret 配置
</a>
</li>
<li class="chapter " data-level="5.2.4" data-path="../guide/resource-quota-management.html">
<a href="../guide/resource-quota-management.html">
<b>5.2.4.</b>
管理 namespace 中的资源配额
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="5.3" data-path="../guide/command-usage.html">
<a href="../guide/command-usage.html">
<b>5.3.</b>
命令使用
</a>
<ul class="articles">
<li class="chapter " data-level="5.3.1" data-path="../guide/docker-cli-to-kubectl.html">
<a href="../guide/docker-cli-to-kubectl.html">
<b>5.3.1.</b>
Docker 用户过渡到 kubectl 命令行指南
</a>
</li>
<li class="chapter " data-level="5.3.2" data-path="../guide/using-kubectl.html">
<a href="../guide/using-kubectl.html">
<b>5.3.2.</b>
kubectl 命令概览
</a>
</li>
<li class="chapter " data-level="5.3.3" data-path="../guide/kubectl-cheatsheet.html">
<a href="../guide/kubectl-cheatsheet.html">
<b>5.3.3.</b>
kubectl 命令技巧大全
</a>
</li>
<li class="chapter " data-level="5.3.4" data-path="../guide/using-etcdctl-to-access-kubernetes-data.html">
<a href="../guide/using-etcdctl-to-access-kubernetes-data.html">
<b>5.3.4.</b>
使用 etcdctl 访问 Kubernetes 数据
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="5.4" data-path="../guide/cluster-security-management.html">
<a href="../guide/cluster-security-management.html">
<b>5.4.</b>
集群安全性管理
</a>
<ul class="articles">
<li class="chapter " data-level="5.4.1" data-path="../guide/managing-tls-in-a-cluster.html">
<a href="../guide/managing-tls-in-a-cluster.html">
<b>5.4.1.</b>
管理集群中的 TLS
</a>
</li>
<li class="chapter " data-level="5.4.2" data-path="../guide/kubelet-authentication-authorization.html">
<a href="../guide/kubelet-authentication-authorization.html">
<b>5.4.2.</b>
kubelet 的认证授权
</a>
</li>
<li class="chapter " data-level="5.4.3" data-path="../guide/tls-bootstrapping.html">
<a href="../guide/tls-bootstrapping.html">
<b>5.4.3.</b>
TLS Bootstrap
</a>
</li>
<li class="chapter " data-level="5.4.4" data-path="../guide/kubectl-user-authentication-authorization.html">
<a href="../guide/kubectl-user-authentication-authorization.html">
<b>5.4.4.</b>
创建用户认证授权的 kubeconfig 文件
</a>
</li>
<li class="chapter " data-level="5.4.5" data-path="../guide/ip-masq-agent.html">
<a href="../guide/ip-masq-agent.html">
<b>5.4.5.</b>
IP 伪装代理
</a>
</li>
<li class="chapter " data-level="5.4.6" data-path="../guide/auth-with-kubeconfig-or-token.html">
<a href="../guide/auth-with-kubeconfig-or-token.html">
<b>5.4.6.</b>
使用 kubeconfig 或 token 进行用户身份认证
</a>
</li>
<li class="chapter " data-level="5.4.7" data-path="../guide/authentication.html">
<a href="../guide/authentication.html">
<b>5.4.7.</b>
Kubernetes 中的用户与身份认证授权
</a>
</li>
<li class="chapter " data-level="5.4.8" data-path="../guide/kubernetes-security-best-practice.html">
<a href="../guide/kubernetes-security-best-practice.html">
<b>5.4.8.</b>
Kubernetes 集群安全性配置最佳实践
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="5.5" data-path="../guide/access-kubernetes-cluster.html">
<a href="../guide/access-kubernetes-cluster.html">
<b>5.5.</b>
访问 Kubernetes 集群
</a>
<ul class="articles">
<li class="chapter " data-level="5.5.1" data-path="../guide/access-cluster.html">
<a href="../guide/access-cluster.html">
<b>5.5.1.</b>
访问集群
</a>
</li>
<li class="chapter " data-level="5.5.2" data-path="../guide/authenticate-across-clusters-kubeconfig.html">
<a href="../guide/authenticate-across-clusters-kubeconfig.html">
<b>5.5.2.</b>
使用 kubeconfig 文件配置跨集群认证
</a>
</li>
<li class="chapter " data-level="5.5.3" data-path="../guide/connecting-to-applications-port-forward.html">
<a href="../guide/connecting-to-applications-port-forward.html">
<b>5.5.3.</b>
通过端口转发访问集群中的应用程序
</a>
</li>
<li class="chapter " data-level="5.5.4" data-path="../guide/service-access-application-cluster.html">
<a href="../guide/service-access-application-cluster.html">
<b>5.5.4.</b>
使用 service 访问群集中的应用程序
</a>
</li>
<li class="chapter " data-level="5.5.5" data-path="../guide/accessing-kubernetes-pods-from-outside-of-the-cluster.html">
<a href="../guide/accessing-kubernetes-pods-from-outside-of-the-cluster.html">
<b>5.5.5.</b>
从外部访问 Kubernetes 中的 Pod
</a>
</li>
<li class="chapter " data-level="5.5.6" data-path="../guide/cabin-mobile-dashboard-for-kubernetes.html">
<a href="../guide/cabin-mobile-dashboard-for-kubernetes.html">
<b>5.5.6.</b>
Cabin - Kubernetes 手机客户端
</a>
</li>
<li class="chapter " data-level="5.5.7" data-path="../guide/kubernetes-desktop-client.html">
<a href="../guide/kubernetes-desktop-client.html">
<b>5.5.7.</b>
Lens - Kubernetes IDE/桌面客户端
</a>
</li>
<li class="chapter " data-level="5.5.8" data-path="../guide/kubernator-kubernetes-ui.html">
<a href="../guide/kubernator-kubernetes-ui.html">
<b>5.5.8.</b>
Kubernator - 更底层的 Kubernetes UI
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="5.6" data-path="../guide/application-development-deployment-flow.html">
<a href="../guide/application-development-deployment-flow.html">
<b>5.6.</b>
在 Kubernetes 中开发部署应用
</a>
<ul class="articles">
<li class="chapter " data-level="5.6.1" data-path="../guide/deploy-applications-in-kubernetes.html">
<a href="../guide/deploy-applications-in-kubernetes.html">
<b>5.6.1.</b>
适用于 Kubernetes 的应用开发部署流程
</a>
</li>
<li class="chapter " data-level="5.6.2" data-path="../guide/migrating-hadoop-yarn-to-kubernetes.html">
<a href="../guide/migrating-hadoop-yarn-to-kubernetes.html">
<b>5.6.2.</b>
迁移传统应用到 Kubernetes 中 —— 以 Hadoop YARN 为例
</a>
</li>
<li class="chapter " data-level="5.6.3" data-path="../guide/using-statefulset.html">
<a href="../guide/using-statefulset.html">
<b>5.6.3.</b>
使用 StatefulSet 部署用状态应用
</a>
</li>
</ul>
</li>
<li class="header">最佳实践</li>
<li class="chapter " data-level="6.1" data-path="../practice/">
<a href="../practice/">
<b>6.1.</b>
最佳实践概览
</a>
</li>
<li class="chapter " data-level="6.2" data-path="../practice/install-kubernetes-on-centos.html">
<a href="../practice/install-kubernetes-on-centos.html">
<b>6.2.</b>
在 CentOS 上部署 Kubernetes 集群
</a>
<ul class="articles">
<li class="chapter " data-level="6.2.1" data-path="../practice/create-tls-and-secret-key.html">
<a href="../practice/create-tls-and-secret-key.html">
<b>6.2.1.</b>
创建 TLS 证书和秘钥
</a>
</li>
<li class="chapter " data-level="6.2.2" data-path="../practice/create-kubeconfig.html">
<a href="../practice/create-kubeconfig.html">
<b>6.2.2.</b>
创建 kubeconfig 文件
</a>
</li>
<li class="chapter " data-level="6.2.3" data-path="../practice/etcd-cluster-installation.html">
<a href="../practice/etcd-cluster-installation.html">
<b>6.2.3.</b>
创建高可用 etcd 集群
</a>
</li>
<li class="chapter " data-level="6.2.4" data-path="../practice/kubectl-installation.html">
<a href="../practice/kubectl-installation.html">
<b>6.2.4.</b>
安装 kubectl 命令行工具
</a>
</li>
<li class="chapter " data-level="6.2.5" data-path="../practice/master-installation.html">
<a href="../practice/master-installation.html">
<b>6.2.5.</b>
部署 master 节点
</a>
</li>
<li class="chapter " data-level="6.2.6" data-path="../practice/flannel-installation.html">
<a href="../practice/flannel-installation.html">
<b>6.2.6.</b>
安装 flannel 网络插件
</a>
</li>
<li class="chapter " data-level="6.2.7" data-path="../practice/node-installation.html">
<a href="../practice/node-installation.html">
<b>6.2.7.</b>
部署 node 节点
</a>
</li>
<li class="chapter " data-level="6.2.8" data-path="../practice/kubedns-addon-installation.html">
<a href="../practice/kubedns-addon-installation.html">
<b>6.2.8.</b>
安装 kubedns 插件
</a>
</li>
<li class="chapter " data-level="6.2.9" data-path="../practice/dashboard-addon-installation.html">
<a href="../practice/dashboard-addon-installation.html">
<b>6.2.9.</b>
安装 dashboard 插件
</a>
</li>
<li class="chapter " data-level="6.2.10" data-path="../practice/heapster-addon-installation.html">
<a href="../practice/heapster-addon-installation.html">
<b>6.2.10.</b>
安装 heapster 插件
</a>
</li>
<li class="chapter " data-level="6.2.11" data-path="../practice/efk-addon-installation.html">
<a href="../practice/efk-addon-installation.html">
<b>6.2.11.</b>
安装 EFK 插件
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.3" data-path="../practice/install-kubernetes-with-kubeadm.html">
<a href="../practice/install-kubernetes-with-kubeadm.html">
<b>6.3.</b>
生产级的 Kubernetes 简化管理工具 kubeadm
</a>
<ul class="articles">
<li class="chapter " data-level="6.3.1" data-path="../practice/install-kubernetes-on-ubuntu-server-16.04-with-kubeadm.html">
<a href="../practice/install-kubernetes-on-ubuntu-server-16.04-with-kubeadm.html">
<b>6.3.1.</b>
使用 kubeadm 在 Ubuntu Server 16.04 上快速构建测试集群
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.4" data-path="../practice/service-discovery-and-loadbalancing.html">
<a href="../practice/service-discovery-and-loadbalancing.html">
<b>6.4.</b>
服务发现与负载均衡
</a>
<ul class="articles">
<li class="chapter " data-level="6.4.1" data-path="../practice/traefik-ingress-installation.html">
<a href="../practice/traefik-ingress-installation.html">
<b>6.4.1.</b>
安装 Traefik ingress
</a>
</li>
<li class="chapter " data-level="6.4.2" data-path="../practice/distributed-load-test.html">
<a href="../practice/distributed-load-test.html">
<b>6.4.2.</b>
分布式负载测试
</a>
</li>
<li class="chapter " data-level="6.4.3" data-path="../practice/network-and-cluster-perfermance-test.html">
<a href="../practice/network-and-cluster-perfermance-test.html">
<b>6.4.3.</b>
网络和集群性能测试
</a>
</li>
<li class="chapter " data-level="6.4.4" data-path="../practice/edge-node-configuration.html">
<a href="../practice/edge-node-configuration.html">
<b>6.4.4.</b>
边缘节点配置
</a>
</li>
<li class="chapter " data-level="6.4.5" data-path="../practice/nginx-ingress-installation.html">
<a href="../practice/nginx-ingress-installation.html">
<b>6.4.5.</b>
安装 Nginx ingress
</a>
</li>
<li class="chapter " data-level="6.4.6" data-path="../practice/dns-installation.html">
<a href="../practice/dns-installation.html">
<b>6.4.6.</b>
安装配置 DNS
</a>
<ul class="articles">
<li class="chapter " data-level="6.4.6.1" data-path="../practice/configuring-dns.html">
<a href="../practice/configuring-dns.html">
<b>6.4.6.1.</b>
安装配置 Kube-dns
</a>
</li>
<li class="chapter " data-level="6.4.6.2" data-path="../practice/coredns.html">
<a href="../practice/coredns.html">
<b>6.4.6.2.</b>
安装配置 CoreDNS
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="6.5" data-path="../practice/operation.html">
<a href="../practice/operation.html">
<b>6.5.</b>
运维管理
</a>
<ul class="articles">
<li class="chapter " data-level="6.5.1" data-path="../practice/master-ha.html">
<a href="../practice/master-ha.html">
<b>6.5.1.</b>
Master 节点高可用
</a>
</li>
<li class="chapter " data-level="6.5.2" data-path="../practice/service-rolling-update.html">
<a href="../practice/service-rolling-update.html">
<b>6.5.2.</b>
服务滚动升级
</a>
</li>
<li class="chapter " data-level="6.5.3" data-path="../practice/app-log-collection.html">
<a href="../practice/app-log-collection.html">
<b>6.5.3.</b>
应用日志收集
</a>
</li>
<li class="chapter " data-level="6.5.4" data-path="../practice/configuration-best-practice.html">
<a href="../practice/configuration-best-practice.html">
<b>6.5.4.</b>
配置最佳实践
</a>
</li>
<li class="chapter " data-level="6.5.5" data-path="../practice/monitor.html">
<a href="../practice/monitor.html">
<b>6.5.5.</b>
集群及应用监控
</a>
</li>
<li class="chapter " data-level="6.5.6" data-path="../practice/data-persistence-problem.html">
<a href="../practice/data-persistence-problem.html">
<b>6.5.6.</b>
数据持久化问题
</a>
</li>
<li class="chapter " data-level="6.5.7" data-path="../practice/manage-compute-resources-container.html">
<a href="../practice/manage-compute-resources-container.html">
<b>6.5.7.</b>
管理容器的计算资源
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.6" data-path="../practice/storage.html">
<a href="../practice/storage.html">
<b>6.6.</b>
存储管理
</a>
<ul class="articles">
<li class="chapter " data-level="6.6.1" data-path="../practice/glusterfs.html">
<a href="../practice/glusterfs.html">
<b>6.6.1.</b>
GlusterFS
</a>
<ul class="articles">
<li class="chapter " data-level="6.6.1.1" data-path="../practice/using-glusterfs-for-persistent-storage.html">
<a href="../practice/using-glusterfs-for-persistent-storage.html">
<b>6.6.1.1.</b>
使用 GlusterFS 做持久化存储
</a>
</li>
<li class="chapter " data-level="6.6.1.2" data-path="../practice/using-heketi-gluster-for-persistent-storage.html">
<a href="../practice/using-heketi-gluster-for-persistent-storage.html">
<b>6.6.1.2.</b>
使用 Heketi 作为 Kubernetes 的持久存储 GlusterFS 的 external provisioner
</a>
</li>
<li class="chapter " data-level="6.6.1.3" data-path="../practice/storage-for-containers-using-glusterfs-with-openshift.html">
<a href="../practice/storage-for-containers-using-glusterfs-with-openshift.html">
<b>6.6.1.3.</b>
在 OpenShift 中使用 GlusterFS 做持久化存储
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.6.2" data-path="../practice/glusterd-2.0.html">
<a href="../practice/glusterd-2.0.html">
<b>6.6.2.</b>
GlusterD-2.0
</a>
</li>
<li class="chapter " data-level="6.6.3" data-path="../practice/ceph.html">
<a href="../practice/ceph.html">
<b>6.6.3.</b>
Ceph
</a>
<ul class="articles">
<li class="chapter " data-level="6.6.3.1" data-path="../practice/ceph-helm-install-guide-zh.html">
<a href="../practice/ceph-helm-install-guide-zh.html">
<b>6.6.3.1.</b>
用 Helm 托管安装 Ceph 集群并提供后端存储
</a>
</li>
<li class="chapter " data-level="6.6.3.2" data-path="../practice/using-ceph-for-persistent-storage.html">
<a href="../practice/using-ceph-for-persistent-storage.html">
<b>6.6.3.2.</b>
使用 Ceph 做持久化存储
</a>
</li>
<li class="chapter " data-level="6.6.3.3" data-path="../practice/rbd-provisioner.html">
<a href="../practice/rbd-provisioner.html">
<b>6.6.3.3.</b>
使用 rbd-provisioner 提供 rbd 持久化存储
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.6.4" data-path="../practice/openebs.html">
<a href="../practice/openebs.html">
<b>6.6.4.</b>
OpenEBS
</a>
<ul class="articles">
<li class="chapter " data-level="6.6.4.1" data-path="../practice/using-openebs-for-persistent-storage.html">
<a href="../practice/using-openebs-for-persistent-storage.html">
<b>6.6.4.1.</b>
使用 OpenEBS 做持久化存储
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.6.5" data-path="../practice/rook.html">
<a href="../practice/rook.html">
<b>6.6.5.</b>
Rook
</a>
</li>
<li class="chapter " data-level="6.6.6" data-path="../practice/nfs.html">
<a href="../practice/nfs.html">
<b>6.6.6.</b>
NFS
</a>
<ul class="articles">
<li class="chapter " data-level="6.6.6.1" data-path="../practice/using-nfs-for-persistent-storage.html">
<a href="../practice/using-nfs-for-persistent-storage.html">
<b>6.6.6.1.</b>
利用 NFS 动态提供 Kubernetes 后端存储卷
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="6.7" data-path="../practice/monitoring.html">
<a href="../practice/monitoring.html">
<b>6.7.</b>
集群与应用监控
</a>
<ul class="articles">
<li class="chapter " data-level="6.7.1" data-path="../practice/heapster.html">
<a href="../practice/heapster.html">
<b>6.7.1.</b>
Heapster
</a>
<ul class="articles">
<li class="chapter " data-level="6.7.1.1" data-path="../practice/using-heapster-to-get-object-metrics.html">
<a href="../practice/using-heapster-to-get-object-metrics.html">
<b>6.7.1.1.</b>
使用 Heapster 获取集群和对象的 metric 数据
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.7.2" data-path="../practice/prometheus.html">
<a href="../practice/prometheus.html">
<b>6.7.2.</b>
Prometheus
</a>
<ul class="articles">
<li class="chapter " data-level="6.7.2.1" data-path="../practice/using-prometheus-to-monitor-kuberentes-cluster.html">
<a href="../practice/using-prometheus-to-monitor-kuberentes-cluster.html">
<b>6.7.2.1.</b>
使用 Prometheus 监控 Kubernetes 集群
</a>
</li>
<li class="chapter " data-level="6.7.2.2" data-path="../practice/promql.html">
<a href="../practice/promql.html">
<b>6.7.2.2.</b>
Prometheus 查询语言 PromQL 使用说明
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.7.3" data-path="../practice/vistio-visualize-your-istio-mesh.html">
<a href="../practice/vistio-visualize-your-istio-mesh.html">
<b>6.7.3.</b>
使用 Vistio 监控 Istio 服务网格中的流量
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.8" data-path="../practice/distributed-tracing.html">
<a href="../practice/distributed-tracing.html">
<b>6.8.</b>
分布式追踪
</a>
<ul class="articles">
<li class="chapter " data-level="6.8.1" data-path="../practice/opentracing.html">
<a href="../practice/opentracing.html">
<b>6.8.1.</b>
OpenTracing
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.9" data-path="../practice/services-management-tool.html">
<a href="../practice/services-management-tool.html">
<b>6.9.</b>
服务编排管理
</a>
<ul class="articles">
<li class="chapter " data-level="6.9.1" data-path="../practice/helm.html">
<a href="../practice/helm.html">
<b>6.9.1.</b>
使用 Helm 管理 Kubernetes 应用
</a>
</li>
<li class="chapter " data-level="6.9.2" data-path="../practice/create-private-charts-repo.html">
<a href="../practice/create-private-charts-repo.html">
<b>6.9.2.</b>
构建私有 Chart 仓库
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.10" data-path="../practice/ci-cd.html">
<a href="../practice/ci-cd.html">
<b>6.10.</b>
持续集成与发布
</a>
<ul class="articles">
<li class="chapter " data-level="6.10.1" data-path="../practice/jenkins-ci-cd.html">
<a href="../practice/jenkins-ci-cd.html">
<b>6.10.1.</b>
使用 Jenkins 进行持续集成与发布
</a>
</li>
<li class="chapter " data-level="6.10.2" data-path="../practice/drone-ci-cd.html">
<a href="../practice/drone-ci-cd.html">
<b>6.10.2.</b>
使用 Drone 进行持续集成与发布
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.11" data-path="../practice/update-and-upgrade.html">
<a href="../practice/update-and-upgrade.html">
<b>6.11.</b>
更新与升级
</a>
<ul class="articles">
<li class="chapter " data-level="6.11.1" data-path="../practice/manually-upgrade.html">
<a href="../practice/manually-upgrade.html">
<b>6.11.1.</b>
手动升级 Kubernetes 集群
</a>
</li>
<li class="chapter " data-level="6.11.2" data-path="../practice/dashboard-upgrade.html">
<a href="../practice/dashboard-upgrade.html">
<b>6.11.2.</b>
升级 dashboard
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="6.12" data-path="../practice/controller-extended.html">
<a href="../practice/controller-extended.html">
<b>6.12.</b>
扩展控制器
</a>
<ul class="articles">
<li class="chapter " data-level="6.12.1" data-path="../practice/openkruise.html">
<a href="../practice/openkruise.html">
<b>6.12.1.</b>
OpenKruise
</a>
<ul class="articles">
<li class="chapter " data-level="6.12.1.1" data-path="../practice/in-place-update.html">
<a href="../practice/in-place-update.html">
<b>6.12.1.1.</b>
原地升级
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="6.13" data-path="../practice/security-policy.html">
<a href="../practice/security-policy.html">
<b>6.13.</b>
安全策略
</a>
<ul class="articles">
<li class="chapter " data-level="6.13.1" data-path="../practice/open-policy-agent.html">
<a href="../practice/open-policy-agent.html">
<b>6.13.1.</b>
开放策略代理OPA
</a>
</li>
<li class="chapter " data-level="6.13.2" data-path="../practice/cloud-native-security.html">
<a href="../practice/cloud-native-security.html">
<b>6.13.2.</b>
云原生安全
</a>
</li>
</ul>
</li>
<li class="header">服务网格</li>
<li class="chapter " data-level="7.1" data-path="../usecases/service-mesh.html">
<a href="../usecases/service-mesh.html">
<b>7.1.</b>
服务网格Service Mesh
</a>
</li>
<li class="chapter " data-level="7.2" data-path="../usecases/the-enterprise-path-to-service-mesh-architectures.html">
<a href="../usecases/the-enterprise-path-to-service-mesh-architectures.html">
<b>7.2.</b>
企业级服务网格架构
</a>
<ul class="articles">
<li class="chapter " data-level="7.2.1" data-path="../usecases/service-mesh-fundamental.html">
<a href="../usecases/service-mesh-fundamental.html">
<b>7.2.1.</b>
服务网格基础
</a>
</li>
<li class="chapter " data-level="7.2.2" data-path="../usecases/comparing-service-mesh-technologies.html">
<a href="../usecases/comparing-service-mesh-technologies.html">
<b>7.2.2.</b>
服务网格技术对比
</a>
</li>
<li class="chapter " data-level="7.2.3" data-path="../usecases/service-mesh-vs-api-gateway.html">
<a href="../usecases/service-mesh-vs-api-gateway.html">
<b>7.2.3.</b>
服务网格对比 API 网关
</a>
</li>
<li class="chapter " data-level="7.2.4" data-path="../usecases/service-mesh-adoption-and-evolution.html">
<a href="../usecases/service-mesh-adoption-and-evolution.html">
<b>7.2.4.</b>
采纳和演进
</a>
</li>
<li class="chapter " data-level="7.2.5" data-path="../usecases/service-mesh-customization-and-integration.html">
<a href="../usecases/service-mesh-customization-and-integration.html">
<b>7.2.5.</b>
定制和集成
</a>
</li>
<li class="chapter " data-level="7.2.6" data-path="../usecases/service-mesh-conclusion.html">
<a href="../usecases/service-mesh-conclusion.html">
<b>7.2.6.</b>
总结
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="7.3" data-path="../usecases/istio.html">
<a href="../usecases/istio.html">
<b>7.3.</b>
Istio
</a>
<ul class="articles">
<li class="chapter " data-level="7.3.1" data-path="../usecases/before-using-istio.html">
<a href="../usecases/before-using-istio.html">
<b>7.3.1.</b>
使用 Istio 前需要考虑的问题
</a>
</li>
<li class="chapter " data-level="7.3.2" data-path="../usecases/sidecar-spec-in-istio.html">
<a href="../usecases/sidecar-spec-in-istio.html">
<b>7.3.2.</b>
Istio 中 sidecar 的注入规范及示例
</a>
</li>
<li class="chapter " data-level="7.3.3" data-path="../usecases/istio-community-tips.html">
<a href="../usecases/istio-community-tips.html">
<b>7.3.3.</b>
如何参与 Istio 社区及注意事项
</a>
</li>
<li class="chapter " data-level="7.3.4" data-path="../usecases/istio-tutorials-collection.html">
<a href="../usecases/istio-tutorials-collection.html">
<b>7.3.4.</b>
Istio 免费学习资源汇总
</a>
</li>
<li class="chapter " data-level="7.3.5" data-path="../usecases/understand-sidecar-injection-and-traffic-hijack-in-istio-service-mesh.html">
<a href="../usecases/understand-sidecar-injection-and-traffic-hijack-in-istio-service-mesh.html">
<b>7.3.5.</b>
Sidecar 的注入与流量劫持
</a>
</li>
<li class="chapter " data-level="7.3.6" data-path="../usecases/envoy-sidecar-routing-of-istio-service-mesh-deep-dive.html">
<a href="../usecases/envoy-sidecar-routing-of-istio-service-mesh-deep-dive.html">
<b>7.3.6.</b>
Envoy Sidecar 代理的路由转发
</a>
</li>
<li class="chapter " data-level="7.3.7" data-path="../usecases/how-to-integrate-istio-with-vm.html">
<a href="../usecases/how-to-integrate-istio-with-vm.html">
<b>7.3.7.</b>
Istio 如何支持虚拟机
</a>
</li>
<li class="chapter " data-level="7.3.8" data-path="../usecases/istio-vm-support.html">
<a href="../usecases/istio-vm-support.html">
<b>7.3.8.</b>
Istio 支持虚拟机的历史
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="7.4" data-path="../usecases/envoy.html">
<a href="../usecases/envoy.html">
<b>7.4.</b>
Envoy
</a>
<ul class="articles">
<li class="chapter " data-level="7.4.1" data-path="../usecases/envoy-terminology.html">
<a href="../usecases/envoy-terminology.html">
<b>7.4.1.</b>
Envoy 的架构与基本术语
</a>
</li>
<li class="chapter " data-level="7.4.2" data-path="../usecases/envoy-front-proxy.html">
<a href="../usecases/envoy-front-proxy.html">
<b>7.4.2.</b>
Envoy 作为前端代理
</a>
</li>
<li class="chapter " data-level="7.4.3" data-path="../usecases/envoy-mesh-in-kubernetes-tutorial.html">
<a href="../usecases/envoy-mesh-in-kubernetes-tutorial.html">
<b>7.4.3.</b>
Envoy mesh 教程
</a>
</li>
</ul>
</li>
<li class="header">领域应用</li>
<li class="chapter " data-level="8.1" data-path="../usecases/">
<a href="../usecases/">
<b>8.1.</b>
领域应用概览
</a>
</li>
<li class="chapter " data-level="8.2" data-path="../usecases/microservices.html">
<a href="../usecases/microservices.html">
<b>8.2.</b>
微服务架构
</a>
<ul class="articles">
<li class="chapter " data-level="8.2.1" data-path="../usecases/service-discovery-in-microservices.html">
<a href="../usecases/service-discovery-in-microservices.html">
<b>8.2.1.</b>
微服务中的服务发现
</a>
</li>
<li class="chapter " data-level="8.2.2" data-path="../usecases/microservices-for-java-developers.html">
<a href="../usecases/microservices-for-java-developers.html">
<b>8.2.2.</b>
使用 Java 构建微服务并发布到 Kubernetes 平台
</a>
<ul class="articles">
<li class="chapter " data-level="8.2.2.1" data-path="../usecases/spring-boot-quick-start-guide.html">
<a href="../usecases/spring-boot-quick-start-guide.html">
<b>8.2.2.1.</b>
Spring Boot 快速开始指南
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="8.3" data-path="../usecases/big-data.html">
<a href="../usecases/big-data.html">
<b>8.3.</b>
大数据
</a>
<ul class="articles">
<li class="chapter " data-level="8.3.1" data-path="../usecases/spark-on-kubernetes.html">
<a href="../usecases/spark-on-kubernetes.html">
<b>8.3.1.</b>
Spark 与 Kubernetes
</a>
<ul class="articles">
<li class="chapter " data-level="8.3.1.1" data-path="../usecases/spark-standalone-on-kubernetes.html">
<a href="../usecases/spark-standalone-on-kubernetes.html">
<b>8.3.1.1.</b>
Spark standalone on Kubernetes
</a>
</li>
<li class="chapter " data-level="8.3.1.2" data-path="../usecases/running-spark-with-kubernetes-native-scheduler.html">
<a href="../usecases/running-spark-with-kubernetes-native-scheduler.html">
<b>8.3.1.2.</b>
运行支持 Kubernetes 原生调度的 Spark 程序
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="chapter " data-level="8.4" data-path="../usecases/serverless.html">
<a href="../usecases/serverless.html">
<b>8.4.</b>
Serverless 架构
</a>
<ul class="articles">
<li class="chapter " data-level="8.4.1" data-path="../usecases/understanding-serverless.html">
<a href="../usecases/understanding-serverless.html">
<b>8.4.1.</b>
理解 Serverless
</a>
</li>
<li class="chapter " data-level="8.4.2" data-path="../usecases/faas.html">
<a href="../usecases/faas.html">
<b>8.4.2.</b>
FaaS函数即服务
</a>
<ul class="articles">
<li class="chapter " data-level="8.4.2.1" data-path="../usecases/openfaas-quick-start.html">
<a href="../usecases/openfaas-quick-start.html">
<b>8.4.2.1.</b>
OpenFaaS 快速入门指南
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="8.4.3" data-path="../usecases/knative.html">
<a href="../usecases/knative.html">
<b>8.4.3.</b>
Knative
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="8.5" data-path="../usecases/edge-computing.html">
<a href="../usecases/edge-computing.html">
<b>8.5.</b>
边缘计算
</a>
</li>
<li class="chapter " data-level="8.6" data-path="../usecases/ai.html">
<a href="../usecases/ai.html">
<b>8.6.</b>
人工智能
</a>
</li>
<li class="chapter " data-level="8.7" data-path="../usecases/observability.html">
<a href="../usecases/observability.html">
<b>8.7.</b>
可观察性
</a>
</li>
<li class="header">开发指南</li>
<li class="chapter " data-level="9.1" data-path="./">
<a href="./">
<b>9.1.</b>
开发指南概览
</a>
</li>
<li class="chapter " data-level="9.2" data-path="sigs-and-working-group.html">
<a href="sigs-and-working-group.html">
<b>9.2.</b>
SIG 和工作组
</a>
</li>
<li class="chapter " data-level="9.3" data-path="developing-environment.html">
<a href="developing-environment.html">
<b>9.3.</b>
开发环境搭建
</a>
<ul class="articles">
<li class="chapter " data-level="9.3.1" data-path="using-vagrant-and-virtualbox-for-development.html">
<a href="using-vagrant-and-virtualbox-for-development.html">
<b>9.3.1.</b>
本地分布式开发环境搭建(使用 Vagrant 和 Virtualbox
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="9.4" data-path="testing.html">
<a href="testing.html">
<b>9.4.</b>
单元测试和集成测试
</a>
</li>
<li class="chapter " data-level="9.5" data-path="client-go-sample.html">
<a href="client-go-sample.html">
<b>9.5.</b>
client-go 示例
</a>
<ul class="articles">
<li class="chapter active" data-level="9.5.1" data-path="client-go-informer-sourcecode-analyse.html">
<a href="client-go-informer-sourcecode-analyse.html">
<b>9.5.1.</b>
client-go 中的 informer 源码分析
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="9.6" data-path="operator.html">
<a href="operator.html">
<b>9.6.</b>
Operator
</a>
<ul class="articles">
<li class="chapter " data-level="9.6.1" data-path="operator-sdk.html">
<a href="operator-sdk.html">
<b>9.6.1.</b>
operator-sdk
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="9.7" data-path="kubebuilder.html">
<a href="kubebuilder.html">
<b>9.7.</b>
kubebuilder
</a>
<ul class="articles">
<li class="chapter " data-level="9.7.1" data-path="kubebuilder-example.html">
<a href="kubebuilder-example.html">
<b>9.7.1.</b>
使用 kubebuilder 创建 operator 示例
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="9.8" data-path="advance-developer.html">
<a href="advance-developer.html">
<b>9.8.</b>
高级开发指南
</a>
</li>
<li class="chapter " data-level="9.9" data-path="contribute.html">
<a href="contribute.html">
<b>9.9.</b>
社区贡献
</a>
</li>
<li class="chapter " data-level="9.10" data-path="minikube.html">
<a href="minikube.html">
<b>9.10.</b>
Minikube
</a>
</li>
<li class="header">社区及生态</li>
<li class="chapter " data-level="10.1" data-path="../cloud-native/cncf.html">
<a href="../cloud-native/cncf.html">
<b>10.1.</b>
云原生计算基金会CNCF
</a>
<ul class="articles">
<li class="chapter " data-level="10.1.1" data-path="../cloud-native/cncf-charter.html">
<a href="../cloud-native/cncf-charter.html">
<b>10.1.1.</b>
CNCF 章程
</a>
</li>
<li class="chapter " data-level="10.1.2" data-path="../cloud-native/cncf-sig.html">
<a href="../cloud-native/cncf-sig.html">
<b>10.1.2.</b>
CNCF 特别兴趣小组SIG说明
</a>
</li>
<li class="chapter " data-level="10.1.3" data-path="../cloud-native/cncf-sandbox-criteria.html">
<a href="../cloud-native/cncf-sandbox-criteria.html">
<b>10.1.3.</b>
开源项目加入 CNCF Sandbox 的要求
</a>
</li>
<li class="chapter " data-level="10.1.4" data-path="../cloud-native/cncf-project-governing.html">
<a href="../cloud-native/cncf-project-governing.html">
<b>10.1.4.</b>
CNCF 中的项目治理
</a>
</li>
<li class="chapter " data-level="10.1.5" data-path="../cloud-native/cncf-ambassador.html">
<a href="../cloud-native/cncf-ambassador.html">
<b>10.1.5.</b>
CNCF Ambassador
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="10.2" data-path="../cloud-native/certification.html">
<a href="../cloud-native/certification.html">
<b>10.2.</b>
认证及培训
</a>
<ul class="articles">
<li class="chapter " data-level="10.2.1" data-path="../appendix/about-kcsp.html">
<a href="../appendix/about-kcsp.html">
<b>10.2.1.</b>
认证 Kubernetes 服务提供商KCSP说明
</a>
</li>
<li class="chapter " data-level="10.2.2" data-path="../appendix/about-cka-candidate.html">
<a href="../appendix/about-cka-candidate.html">
<b>10.2.2.</b>
认证 Kubernetes 管理员CKA说明
</a>
</li>
</ul>
</li>
<li class="header">附录</li>
<li class="chapter " data-level="11.1" data-path="../appendix/">
<a href="../appendix/">
<b>11.1.</b>
附录说明
</a>
</li>
<li class="chapter " data-level="11.2" data-path="../appendix/debug-kubernetes-services.html">
<a href="../appendix/debug-kubernetes-services.html">
<b>11.2.</b>
Kubernetes 中的应用故障排查
</a>
</li>
<li class="chapter " data-level="11.3" data-path="../appendix/material-share.html">
<a href="../appendix/material-share.html">
<b>11.3.</b>
Kubernetes 相关资讯和情报链接
</a>
</li>
<li class="chapter " data-level="11.4" data-path="../appendix/docker-best-practice.html">
<a href="../appendix/docker-best-practice.html">
<b>11.4.</b>
Docker 最佳实践
</a>
</li>
<li class="chapter " data-level="11.5" data-path="../appendix/tricks.html">
<a href="../appendix/tricks.html">
<b>11.5.</b>
Kubernetes 使用技巧
</a>
</li>
<li class="chapter " data-level="11.6" data-path="../appendix/issues.html">
<a href="../appendix/issues.html">
<b>11.6.</b>
Kubernetes 相关问题记录
</a>
</li>
<li class="chapter " data-level="11.7" data-path="../appendix/summary-and-outlook.html">
<a href="../appendix/summary-and-outlook.html">
<b>11.7.</b>
Kubernetes 及云原生年度总结及展望
</a>
<ul class="articles">
<li class="chapter " data-level="11.7.1" data-path="../appendix/kubernetes-and-cloud-native-summary-in-2017-and-outlook-for-2018.html">
<a href="../appendix/kubernetes-and-cloud-native-summary-in-2017-and-outlook-for-2018.html">
<b>11.7.1.</b>
Kubernetes 与云原生 2017 年年终总结及 2018 年展望
</a>
</li>
<li class="chapter " data-level="11.7.2" data-path="../appendix/kubernetes-and-cloud-native-summary-in-2018-and-outlook-for-2019.html">
<a href="../appendix/kubernetes-and-cloud-native-summary-in-2018-and-outlook-for-2019.html">
<b>11.7.2.</b>
Kubernetes 与云原生 2018 年年终总结及 2019 年展望
</a>
</li>
</ul>
</li>
<li class="chapter " data-level="11.8" data-path="../appendix/cncf-annual-report.html">
<a href="../appendix/cncf-annual-report.html">
<b>11.8.</b>
CNCF 年度报告解读
</a>
<ul class="articles">
<li class="chapter " data-level="11.8.1" data-path="../appendix/cncf-annual-report-2018.html">
<a href="../appendix/cncf-annual-report-2018.html">
<b>11.8.1.</b>
CNCF 2018 年年度报告解读
</a>
</li>
<li class="chapter " data-level="11.8.2" data-path="../appendix/cncf-annual-report-2020.html">
<a href="../appendix/cncf-annual-report-2020.html">
<b>11.8.2.</b>
CNCF 2020 年年度报告解读
</a>
</li>
</ul>
</li>
<li class="divider"></li>
<li>
<a href="https://www.gitbook.com" target="blank" class="gitbook-link">
本书使用 GitBook 发布
</a>
</li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<!-- Title -->
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i>
<a href=".." >client-go 中的 informer 源码分析</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<div class="search-plus" id="book-search-results">
<div class="search-noresults">
<section class="normal markdown-section">
<h1 id="client-go-&#x4E2D;&#x7684;-informer-&#x6E90;&#x7801;&#x5206;&#x6790;">client-go &#x4E2D;&#x7684; informer &#x6E90;&#x7801;&#x5206;&#x6790;</h1>
<p>&#x672C;&#x6587;&#x5C06;&#x4EE5;&#x56FE;&#x6587;&#x5E76;&#x8302;&#x7684;&#x65B9;&#x5F0F;&#x5BF9; client-go &#x4E2D;&#x7684; informer &#x7684;&#x6E90;&#x7801;&#x5206;&#x6790;&#xFF0C;&#x5176;&#x6574;&#x4F53;&#x6D41;&#x7A0B;&#x56FE;&#x5982;&#x4E0B;&#x6240;&#x793A;&#x3002;</p>
<figure id="fig9.5.1.1"><a href="../images/client-go-informer.png" data-lightbox="3c02b413-aa80-43d0-848e-e1b9e3f3f493" data-title="client-go informer"><img src="../images/client-go-informer.png" alt="client-go informer"></a><figcaption>&#x56FE; 9.5.1.1&#xFF1A;client-go informer</figcaption></figure>
<h2 id="&#x524D;&#x8A00;">&#x524D;&#x8A00;</h2>
<p>Kubernetes&#x4F5C;&#x4E3A;&#x65B0;&#x4E00;&#x4EE3;&#x7684;&#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x7CFB;&#x7EDF;&#xFF0C;&#x5176;&#x91CD;&#x8981;&#x6027;&#x5DF2;&#x7ECF;&#x4E0D;&#x8A00;&#x800C;&#x55BB;&#x4E86;&#x3002;&#x57FA;&#x4E8E;&#x63A7;&#x5236;&#x5668;&#x6A21;&#x578B;&#x5B9E;&#x73B0;&#x7684;&#x58F0;&#x660E;&#x5F0F;API&#x652F;&#x6301;&#x7740;&#x96C6;&#x7FA4;&#x4E2D;&#x5404;&#x7C7B;&#x578B;&#x7684;&#x5DE5;&#x4F5C;&#x8D1F;&#x8F7D;&#x7A33;&#x5B9A;&#x9AD8;&#x6548;&#x7684;&#x6309;&#x7167;&#x671F;&#x671B;&#x72B6;&#x6001;&#x8FD0;&#x8F6C;&#xFF0C;&#x968F;&#x7740;&#x8D8A;&#x6765;&#x8D8A;&#x591A;&#x7684;&#x7528;&#x6237;&#x9009;&#x62E9;kubernetes&#xFF0C;&#x65E0;&#x8BBA;&#x662F;&#x4E3A;&#x4E86;&#x6DF1;&#x5165;&#x4E86;&#x89E3;kubernetes&#x8FD9;&#x4E00;&#x4E91;&#x539F;&#x751F;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x7684;&#x5DE5;&#x4F5C;&#x903B;&#x8F91;&#xFF0C;&#x8FD8;&#x662F;&#x671F;&#x5F85;&#x80FD;&#x591F;&#x6839;&#x636E;&#x81EA;&#x5DF1;&#x7684;&#x7279;&#x5B9A;&#x4E1A;&#x52A1;&#x9700;&#x6C42;&#x5BF9;kubernetes&#x8FDB;&#x884C;&#x4E8C;&#x6B21;&#x5F00;&#x53D1;&#xFF0C;&#x4E86;&#x89E3;&#x63A7;&#x5236;&#x5668;&#x6A21;&#x578B;&#x7684;&#x5B9E;&#x73B0;&#x673A;&#x5236;&#x90FD;&#x662F;&#x975E;&#x5E38;&#x91CD;&#x8981;&#x7684;&#x3002;kubernetes&#x63D0;&#x4F9B;&#x4E86;client-go&#x4EE5;&#x65B9;&#x4FBF;&#x4F7F;&#x7528;go&#x8BED;&#x8A00;&#x8FDB;&#x884C;&#x4E8C;&#x6B21;&#x5FEB;&#x53D1;&#xFF0C;&#x672C;&#x6587;&#x8BD5;&#x56FE;&#x8BB2;&#x8FF0;client-go&#x5404;&#x6A21;&#x5757;&#x5982;informer&#x3001;reflector&#x3001;cache&#x7B49;&#x5B9E;&#x73B0;&#x7EC6;&#x8282;&#x3002;</p>
<p>&#x5F53;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x5229;&#x7528;client-go&#x6765;&#x5B9E;&#x73B0;&#x81EA;&#x5B9A;&#x4E49;&#x63A7;&#x5236;&#x5668;&#x65F6;&#xFF0C;&#x901A;&#x5E38;&#x4F1A;&#x4F7F;&#x7528;informerFactory&#x6765;&#x7BA1;&#x7406;&#x63A7;&#x5236;&#x5668;&#x9700;&#x8981;&#x7684;&#x591A;&#x4E2A;&#x8D44;&#x6E90;&#x5BF9;&#x8C61;&#x7684;informer&#x5B9E;&#x4F8B;</p>
<pre class="language-"><code class="lang-go"><span class="token comment">// &#x521B;&#x5EFA;&#x4E00;&#x4E2A;informer factory</span>
kubeInformerFactory <span class="token operator">:=</span> kubeinformers<span class="token punctuation">.</span><span class="token function">NewSharedInformerFactory</span><span class="token punctuation">(</span>kubeClient<span class="token punctuation">,</span> time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">30</span><span class="token punctuation">)</span>
<span class="token comment">// factory&#x5DF2;&#x7ECF;&#x4E3A;&#x6240;&#x6709;k8s&#x7684;&#x5185;&#x7F6E;&#x8D44;&#x6E90;&#x5BF9;&#x8C61;&#x63D0;&#x4F9B;&#x4E86;&#x521B;&#x5EFA;&#x5BF9;&#x5E94;informer&#x5B9E;&#x4F8B;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x8C03;&#x7528;&#x5177;&#x4F53;informer&#x5B9E;&#x4F8B;&#x7684;Lister&#x6216;Informer&#x65B9;&#x6CD5;</span>
<span class="token comment">// &#x5C31;&#x5B8C;&#x6210;&#x4E86;&#x5C06;informer&#x6CE8;&#x518C;&#x5230;factory&#x7684;&#x8FC7;&#x7A0B;</span>
deploymentLister <span class="token operator">:=</span> kubeInformerFactory<span class="token punctuation">.</span><span class="token function">Apps</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">V1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Deployments</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Lister</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// &#x542F;&#x52A8;&#x6CE8;&#x518C;&#x5230;factory&#x7684;&#x6240;&#x6709;informer</span>
kubeInformerFactory<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span>stopCh<span class="token punctuation">)</span>
</code></pre>
<h3 id="sharedinformerfactory&#x7ED3;&#x6784;">SharedInformerFactory&#x7ED3;&#x6784;</h3>
<p>&#x4F7F;&#x7528;sharedInformerFactory&#x53EF;&#x4EE5;&#x7EDF;&#x4E00;&#x7BA1;&#x7406;&#x63A7;&#x5236;&#x5668;&#x4E2D;&#x9700;&#x8981;&#x7684;&#x5404;&#x8D44;&#x6E90;&#x5BF9;&#x8C61;&#x7684;informer&#x5B9E;&#x4F8B;&#xFF0C;&#x907F;&#x514D;&#x540C;&#x4E00;&#x4E2A;&#x8D44;&#x6E90;&#x521B;&#x5EFA;&#x591A;&#x4E2A;&#x5B9E;&#x4F8B;&#xFF0C;&#x8FD9;&#x91CC;&#x7684;informer&#x5B9E;&#x73B0;&#x662F;shareIndexInformer
NewSharedInformerFactory&#x8C03;&#x7528;&#x4E86;NewSharedInformerFactoryWithOptions&#xFF0C;&#x5C06;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;sharedInformerFactory&#x5BF9;&#x8C61;</p>
<blockquote>
<p>client: clientset&#xFF0C;&#x652F;&#x6301;&#x76F4;&#x63A5;&#x8BF7;&#x6C42;api&#x4E2D;&#x5404;&#x5185;&#x7F6E;&#x8D44;&#x6E90;&#x5BF9;&#x8C61;&#x7684;restful group&#x5BA2;&#x6237;&#x7AEF;&#x96C6;&#x5408;
namespace: factory&#x5173;&#x6CE8;&#x7684;namespace&#xFF08;&#x9ED8;&#x8BA4;All Namespace&#xFF09;&#xFF0C;informer&#x4E2D;&#x7684;reflector&#x5C06;&#x53EA;&#x4F1A;listAndWatch&#x6307;&#x5B9A;namespace&#x7684;&#x8D44;&#x6E90;
defaultResync: &#x7528;&#x4E8E;&#x521D;&#x59CB;&#x5316;&#x6301;&#x6709;&#x7684;shareIndexInformer&#x7684;resyncCheckPeriod&#x548C;defaultEventHandlerResyncPeriod&#x5B57;&#x6BB5;&#xFF0C;&#x7528;&#x4E8E;&#x5B9A;&#x65F6;&#x7684;&#x5C06;local store&#x540C;&#x6B65;&#x5230;deltaFIFO
customResync&#xFF1A;&#x652F;&#x6301;&#x9488;&#x5BF9;&#x6BCF;&#x4E00;&#x4E2A;informer&#x6765;&#x914D;&#x7F6E;resync&#x65F6;&#x95F4;&#xFF0C;&#x901A;&#x8FC7;WithCustomResyncConfig&#x8FD9;&#x4E2A;Option&#x914D;&#x7F6E;&#xFF0C;&#x5426;&#x5219;&#x5C31;&#x7528;&#x6307;&#x5B9A;&#x7684;defaultResync
informers&#xFF1A;factory&#x7BA1;&#x7406;&#x7684;informer&#x96C6;&#x5408;
startedInformers&#xFF1A;&#x8BB0;&#x5F55;&#x5DF2;&#x7ECF;&#x542F;&#x52A8;&#x7684;informer&#x96C6;&#x5408;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">type</span> sharedInformerFactory <span class="token keyword">struct</span> <span class="token punctuation">{</span>
client kubernetes<span class="token punctuation">.</span>Interface <span class="token comment">//clientset</span>
namespace <span class="token builtin">string</span> <span class="token comment">//&#x5173;&#x6CE8;&#x7684;namepace&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;WithNamespace Option&#x914D;&#x7F6E;</span>
tweakListOptions internalinterfaces<span class="token punctuation">.</span>TweakListOptionsFunc
lock sync<span class="token punctuation">.</span>Mutex
defaultResync time<span class="token punctuation">.</span>Duration <span class="token comment">//&#x524D;&#x9762;&#x4F20;&#x8FC7;&#x6765;&#x7684;&#x65F6;&#x95F4;&#xFF0C;&#x5982;30s</span>
customResync <span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span>time<span class="token punctuation">.</span>Duration <span class="token comment">//&#x81EA;&#x5B9A;&#x4E49;resync&#x65F6;&#x95F4;</span>
informers <span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span>cache<span class="token punctuation">.</span>SharedIndexInformer <span class="token comment">//&#x9488;&#x5BF9;&#x6BCF;&#x79CD;&#x7C7B;&#x578B;&#x8D44;&#x6E90;&#x5B58;&#x50A8;&#x4E00;&#x4E2A;informer&#xFF0C;informer&#x7684;&#x7C7B;&#x578B;&#x662F;ShareIndexInformer</span>
startedInformers <span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span><span class="token builtin">bool</span> <span class="token comment">//&#x6BCF;&#x4E2A;informer&#x662F;&#x5426;&#x90FD;&#x542F;&#x52A8;&#x4E86;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>sharedInformerFactory&#x5BF9;&#x8C61;&#x7684;&#x5173;&#x952E;&#x65B9;&#x6CD5;&#xFF1A;</p>
<h4 id="&#x521B;&#x5EFA;&#x4E00;&#x4E2A;sharedinformerfactory">&#x521B;&#x5EFA;&#x4E00;&#x4E2A;sharedInformerFactory</h4>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token function">NewSharedInformerFactoryWithOptions</span><span class="token punctuation">(</span>client kubernetes<span class="token punctuation">.</span>Interface<span class="token punctuation">,</span> defaultResync time<span class="token punctuation">.</span>Duration<span class="token punctuation">,</span> options <span class="token operator">...</span>SharedInformerOption<span class="token punctuation">)</span> SharedInformerFactory <span class="token punctuation">{</span>
factory <span class="token operator">:=</span> <span class="token operator">&amp;</span>sharedInformerFactory<span class="token punctuation">{</span>
client<span class="token punctuation">:</span> client<span class="token punctuation">,</span> <span class="token comment">//clientset&#xFF0C;&#x5BF9;&#x539F;&#x751F;&#x8D44;&#x6E90;&#x6765;&#x8BF4;&#xFF0C;&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x4F7F;&#x7528;kube clientset</span>
namespace<span class="token punctuation">:</span> v1<span class="token punctuation">.</span>NamespaceAll<span class="token punctuation">,</span> <span class="token comment">//&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x9ED8;&#x8BA4;&#x662F;&#x76D1;&#x542C;&#x6240;&#x6709;ns&#x4E0B;&#x7684;&#x6307;&#x5B9A;&#x8D44;&#x6E90;</span>
defaultResync<span class="token punctuation">:</span> defaultResync<span class="token punctuation">,</span> <span class="token comment">//30s</span>
<span class="token comment">//&#x4EE5;&#x4E0B;&#x521D;&#x59CB;&#x5316;map&#x7ED3;&#x6784;</span>
informers<span class="token punctuation">:</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span>cache<span class="token punctuation">.</span>SharedIndexInformer<span class="token punctuation">)</span><span class="token punctuation">,</span>
startedInformers<span class="token punctuation">:</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span><span class="token builtin">bool</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
customResync<span class="token punctuation">:</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span>time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> factory
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x542F;&#x52A8;factory&#x4E0B;&#x7684;&#x6240;&#x6709;informer">&#x542F;&#x52A8;factory&#x4E0B;&#x7684;&#x6240;&#x6709;informer</h4>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>sharedInformerFactory<span class="token punctuation">)</span> <span class="token function">Start</span><span class="token punctuation">(</span>stopCh <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> informerType<span class="token punctuation">,</span> informer <span class="token operator">:=</span> <span class="token keyword">range</span> f<span class="token punctuation">.</span>informers <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token operator">!</span>f<span class="token punctuation">.</span>startedInformers<span class="token punctuation">[</span>informerType<span class="token punctuation">]</span> <span class="token punctuation">{</span>
<span class="token comment">//&#x76F4;&#x63A5;&#x8D77;gorouting&#x8C03;&#x7528;informer&#x7684;Run&#x65B9;&#x6CD5;&#xFF0C;&#x5E76;&#x4E14;&#x6807;&#x8BB0;&#x5BF9;&#x5E94;&#x7684;informer&#x5DF2;&#x7ECF;&#x542F;&#x52A8;</span>
<span class="token keyword">go</span> informer<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>stopCh<span class="token punctuation">)</span>
f<span class="token punctuation">.</span>startedInformers<span class="token punctuation">[</span>informerType<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x7B49;&#x5F85;informer&#x7684;cache&#x88AB;&#x540C;&#x6B65;">&#x7B49;&#x5F85;informer&#x7684;cache&#x88AB;&#x540C;&#x6B65;</h4>
<p>&#x7B49;&#x5F85;&#x6BCF;&#x4E00;&#x4E2A;ShareIndexInformer&#x7684;cache&#x88AB;&#x540C;&#x6B65;&#xFF0C;&#x5177;&#x4F53;&#x600E;&#x4E48;&#x7B97;&#x540C;&#x6B65;&#x5B8C;&#x6210;&#xFF1F;</p>
<ul>
<li><p>sharedInformerFactory&#x7684;WaitForCacheSync&#x5C06;&#x4F1A;&#x4E0D;&#x65AD;&#x8C03;&#x7528;factory&#x6301;&#x6709;&#x7684;&#x6240;&#x6709;informer&#x7684;HasSynced&#x65B9;&#x6CD5;&#xFF0C;&#x76F4;&#x5230;&#x8FD4;&#x56DE;true</p>
</li>
<li><p>&#x800C;informer&#x7684;HasSynced&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x7684;&#x81EA;&#x5DF1;&#x6301;&#x6709;&#x7684;controller&#x7684;HasSynced&#x65B9;&#x6CD5;&#xFF08;informer&#x7ED3;&#x6784;&#x6301;&#x6709;controller&#x5BF9;&#x8C61;&#xFF0C;&#x4E0B;&#x6587;&#x4F1A;&#x5206;&#x6790;informer&#x7684;&#x7ED3;&#x6784;&#xFF09;</p>
</li>
<li><p>informer&#x4E2D;&#x7684;controller&#x7684;HasSynced&#x65B9;&#x6CD5;&#x5219;&#x8C03;&#x7528;&#x7684;&#x662F;controller&#x6301;&#x6709;&#x7684;deltaFIFO&#x5BF9;&#x8C61;&#x7684;HasSynced&#x65B9;&#x6CD5;</p>
</li>
</ul>
<p>&#x4E5F;&#x5C31;&#x8BF4;sharedInformerFactory&#x7684;WaitForCacheSync&#x65B9;&#x6CD5;&#x5224;&#x65AD;informer&#x7684;cache&#x662F;&#x5426;&#x540C;&#x6B65;&#xFF0C;&#x6700;&#x7EC8;&#x770B;&#x7684;&#x662F;informer&#x4E2D;&#x7684;deltaFIFO&#x662F;&#x5426;&#x540C;&#x6B65;&#x4E86;&#xFF0C;deltaFIFO&#x7684;&#x7ED3;&#x6784;&#x4E0B;&#x6587;&#x5C06;&#x4F1A;&#x5206;&#x6790;</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>sharedInformerFactory<span class="token punctuation">)</span> <span class="token function">WaitForCacheSync</span><span class="token punctuation">(</span>stopCh <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span><span class="token builtin">bool</span> <span class="token punctuation">{</span>
<span class="token comment">//&#x83B7;&#x53D6;&#x6BCF;&#x4E00;&#x4E2A;&#x5DF2;&#x7ECF;&#x542F;&#x52A8;&#x7684;informer</span>
informers <span class="token operator">:=</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span>cache<span class="token punctuation">.</span>SharedIndexInformer <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
informers <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span>cache<span class="token punctuation">.</span>SharedIndexInformer<span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">for</span> informerType<span class="token punctuation">,</span> informer <span class="token operator">:=</span> <span class="token keyword">range</span> f<span class="token punctuation">.</span>informers <span class="token punctuation">{</span>
<span class="token keyword">if</span> f<span class="token punctuation">.</span>startedInformers<span class="token punctuation">[</span>informerType<span class="token punctuation">]</span> <span class="token punctuation">{</span>
informers<span class="token punctuation">[</span>informerType<span class="token punctuation">]</span> <span class="token operator">=</span> informer
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> informers
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
res <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span>reflect<span class="token punctuation">.</span>Type<span class="token punctuation">]</span><span class="token builtin">bool</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">// &#x7B49;&#x5F85;&#x4ED6;&#x4EEC;&#x7684;cache&#x88AB;&#x540C;&#x6B65;&#xFF0C;&#x8C03;&#x7528;&#x7684;&#x662F;informer&#x7684;HasSynced&#x65B9;&#x6CD5;</span>
<span class="token keyword">for</span> informType<span class="token punctuation">,</span> informer <span class="token operator">:=</span> <span class="token keyword">range</span> informers <span class="token punctuation">{</span>
res<span class="token punctuation">[</span>informType<span class="token punctuation">]</span> <span class="token operator">=</span> cache<span class="token punctuation">.</span><span class="token function">WaitForCacheSync</span><span class="token punctuation">(</span>stopCh<span class="token punctuation">,</span> informer<span class="token punctuation">.</span>HasSynced<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> res
<span class="token punctuation">}</span>
</code></pre>
<h4 id="factory&#x4E3A;&#x81EA;&#x5DF1;&#x6DFB;&#x52A0;informer">factory&#x4E3A;&#x81EA;&#x5DF1;&#x6DFB;&#x52A0;informer</h4>
<p>&#x53EA;&#x6709;&#x5411;factory&#x4E2D;&#x6DFB;&#x52A0;informer&#xFF0C;factory&#x624D;&#x6709;&#x610F;&#x4E49;&#xFF0C;&#x6DFB;&#x52A0;&#x5B8C;&#x6210;&#x4E4B;&#x540E;&#xFF0C;&#x4E0A;&#x9762;factory&#x7684;start&#x65B9;&#x6CD5;&#x5C31;&#x53EF;&#x4EE5;&#x542F;&#x52A8;&#x4E86;</p>
<blockquote>
<p>obj: informer&#x5173;&#x6CE8;&#x7684;&#x8D44;&#x6E90;&#x5982;deployment{}
newFunc: &#x4E00;&#x4E2A;&#x77E5;&#x9053;&#x5982;&#x4F55;&#x521B;&#x5EFA;&#x6307;&#x5B9A;informer&#x7684;&#x65B9;&#x6CD5;&#xFF0C;k8s&#x4E3A;&#x6BCF;&#x4E00;&#x4E2A;&#x5185;&#x7F6E;&#x7684;&#x5BF9;&#x8C61;&#x90FD;&#x5B9E;&#x73B0;&#x4E86;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#xFF0C;&#x6BD4;&#x5982;&#x521B;&#x5EFA;deployment&#x7684;ShareIndexInformer&#x7684;&#x65B9;&#x6CD5;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token comment">// &#x5411;factory&#x4E2D;&#x6CE8;&#x518C;&#x6307;&#x5B9A;&#x7684;informer</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>sharedInformerFactory<span class="token punctuation">)</span> <span class="token function">InformerFor</span><span class="token punctuation">(</span>obj runtime<span class="token punctuation">.</span>Object<span class="token punctuation">,</span> newFunc internalinterfaces<span class="token punctuation">.</span>NewInformerFunc<span class="token punctuation">)</span> cache<span class="token punctuation">.</span>SharedIndexInformer <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">//&#x6839;&#x636E;&#x5BF9;&#x8C61;&#x7C7B;&#x578B;&#x5224;&#x65AD;factory&#x4E2D;&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x6709;&#x5BF9;&#x5E94;informer</span>
informerType <span class="token operator">:=</span> reflect<span class="token punctuation">.</span><span class="token function">TypeOf</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
informer<span class="token punctuation">,</span> exists <span class="token operator">:=</span> f<span class="token punctuation">.</span>informers<span class="token punctuation">[</span>informerType<span class="token punctuation">]</span>
<span class="token keyword">if</span> exists <span class="token punctuation">{</span>
<span class="token keyword">return</span> informer
<span class="token punctuation">}</span>
<span class="token comment">//&#x5982;&#x679C;factory&#x4E2D;&#x5DF2;&#x7ECF;&#x6709;&#x8FD9;&#x4E2A;&#x5BF9;&#x8C61;&#x7C7B;&#x578B;&#x7684;informer&#xFF0C;&#x5C31;&#x4E0D;&#x521B;&#x5EFA;&#x4E86;</span>
resyncPeriod<span class="token punctuation">,</span> exists <span class="token operator">:=</span> f<span class="token punctuation">.</span>customResync<span class="token punctuation">[</span>informerType<span class="token punctuation">]</span>
<span class="token keyword">if</span> <span class="token operator">!</span>exists <span class="token punctuation">{</span>
resyncPeriod <span class="token operator">=</span> f<span class="token punctuation">.</span>defaultResync
<span class="token punctuation">}</span>
<span class="token comment">//&#x6CA1;&#x6709;&#x5C31;&#x6839;&#x636E;newFunc&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#xFF0C;&#x5E76;&#x5B58;&#x5728;map&#x4E2D;</span>
informer <span class="token operator">=</span> <span class="token function">newFunc</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>client<span class="token punctuation">,</span> resyncPeriod<span class="token punctuation">)</span>
f<span class="token punctuation">.</span>informers<span class="token punctuation">[</span>informerType<span class="token punctuation">]</span> <span class="token operator">=</span> informer
<span class="token keyword">return</span> informer
<span class="token punctuation">}</span>
</code></pre>
<h5 id="shareindexinformer&#x5BF9;&#x5E94;&#x7684;newfunc&#x7684;&#x5B9E;&#x73B0;">shareIndexInformer&#x5BF9;&#x5E94;&#x7684;newFunc&#x7684;&#x5B9E;&#x73B0;</h5>
<p>client-go&#x4E2D;&#x5DF2;&#x7ECF;&#x4E3A;&#x6240;&#x6709;&#x5185;&#x7F6E;&#x5BF9;&#x8C61;&#x90FD;&#x63D0;&#x4F9B;&#x4E86;NewInformerFunc</p>
<p>&#x4EE5;deployment&#x4E3A;&#x4F8B;&#xFF0C;&#x901A;&#x8FC7;&#x8C03;&#x7528;factory.Apps().V1().Deployments()&#x5373;&#x53EF;&#x4E3A;factory&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;deployment&#x5BF9;&#x5E94;&#x7684;shareIndexInformer&#x7684;&#x5B9E;&#x73B0;&#xFF0C;&#x5177;&#x4F53;&#x8FC7;&#x7A0B;&#x5982;&#x4E0B;&#xFF1A;</p>
<ul>
<li>&#x8C03;&#x7528;factory.Apps().V1().Deployments()&#x5373;&#x4F1A;&#x8C03;&#x7528;&#x4EE5;&#x4E0B;Deployments&#x65B9;&#x6CD5;&#x521B;&#x5EFA;deploymentInformer&#x5BF9;&#x8C61;</li>
</ul>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>v <span class="token operator">*</span>version<span class="token punctuation">)</span> <span class="token function">Deployments</span><span class="token punctuation">(</span><span class="token punctuation">)</span> DeploymentInformer <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token operator">&amp;</span>deploymentInformer<span class="token punctuation">{</span>factory<span class="token punctuation">:</span> v<span class="token punctuation">.</span>factory<span class="token punctuation">,</span> namespace<span class="token punctuation">:</span> v<span class="token punctuation">.</span>namespace<span class="token punctuation">,</span> tweakListOptions<span class="token punctuation">:</span> v<span class="token punctuation">.</span>tweakListOptions<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<ul>
<li>&#x53EA;&#x8981;&#x8C03;&#x7528;&#x4E86;factory.Apps().V1().Deployments()&#x8FD4;&#x56DE;&#x7684;deploymentInformer&#x7684;Informer&#x6216;Lister&#x65B9;&#x6CD5;&#xFF0C;&#x5C31;&#x5B8C;&#x6210;&#x4E86;&#x5411;factory&#x4E2D;&#x6DFB;&#x52A0;deployment informer</li>
</ul>
<pre class="language-"><code class="lang-go"><span class="token comment">// deploymentInformer&#x5BF9;&#x8C61;&#x5177;&#x6709;defaultInformer&#x3001;Informer&#x3001;Lister&#x65B9;&#x6CD5;</span>
<span class="token comment">// &#x53EF;&#x4EE5;&#x770B;&#x5230;&#x521B;&#x5EFA;deploymentInformer&#x65F6;&#x4F20;&#x9012;&#x4E86;&#x4E00;&#x4E2A;&#x5E26;&#x7D22;&#x5F15;&#x7684;&#x7F13;&#x5B58;&#xFF0C;&#x9644;&#x5E26;&#x4E86;&#x4E00;&#x4E2A;namespace&#x7D22;&#x5F15;&#xFF0C;&#x540E;&#x9762;&#x53EF;&#x4EE5;&#x4E86;&#x89E3;&#x5E26;&#x7D22;&#x5F15;&#x7684;&#x7F13;&#x5B58;&#x5B9E;&#x73B0;&#xFF0C;&#x6BD4;&#x5982;&#x53EF;&#x4EE5;&#x652F;&#x6301;&#x67E5;&#x8BE2;&#xFF1A;&#x67D0;&#x4E2A;namespace&#x4E0B;&#x7684;&#x6240;&#x6709;pod</span>
<span class="token comment">// &#x7528;&#x4E8E;&#x521B;&#x5EFA;&#x5BF9;&#x5E94;&#x7684;shareIndexInformer&#xFF0C;&#x8BE5;&#x65B9;&#x6CD5;&#x63D0;&#x4F9B;&#x7ED9;factory&#x7684;InformerFor&#x65B9;&#x6CD5;</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>deploymentInformer<span class="token punctuation">)</span> <span class="token function">defaultInformer</span><span class="token punctuation">(</span>client kubernetes<span class="token punctuation">.</span>Interface<span class="token punctuation">,</span> resyncPeriod time<span class="token punctuation">.</span>Duration<span class="token punctuation">)</span> cache<span class="token punctuation">.</span>SharedIndexInformer <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">NewFilteredDeploymentInformer</span><span class="token punctuation">(</span>client<span class="token punctuation">,</span> f<span class="token punctuation">.</span>namespace<span class="token punctuation">,</span> resyncPeriod<span class="token punctuation">,</span> cache<span class="token punctuation">.</span>Indexers<span class="token punctuation">{</span>cache<span class="token punctuation">.</span>NamespaceIndex<span class="token punctuation">:</span> cache<span class="token punctuation">.</span>MetaNamespaceIndexFunc<span class="token punctuation">}</span><span class="token punctuation">,</span> f<span class="token punctuation">.</span>tweakListOptions<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x5411;factor&#x4E2D;&#x6DFB;&#x52A0;dpeloyment&#x7684;shareIndexInformer&#x5E76;&#x8FD4;&#x56DE;</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>deploymentInformer<span class="token punctuation">)</span> <span class="token function">Informer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> cache<span class="token punctuation">.</span>SharedIndexInformer <span class="token punctuation">{</span>
<span class="token keyword">return</span> f<span class="token punctuation">.</span>factory<span class="token punctuation">.</span><span class="token function">InformerFor</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>appsv1<span class="token punctuation">.</span>Deployment<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> f<span class="token punctuation">.</span>defaultInformer<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x8FD4;&#x56DE;dpeloyment&#x7684;lister&#x5BF9;&#x8C61;&#xFF0C;&#x8BE5;lister&#x4E2D;&#x6301;&#x6709;&#x4E0A;&#x9762;&#x521B;&#x5EFA;&#x51FA;&#x7684;shareIndexInformer&#x7684;cache&#x7684;&#x5F15;&#x7528;&#xFF0C;&#x65B9;&#x4FBF;&#x901A;&#x8FC7;&#x7F13;&#x5B58;&#x83B7;&#x53D6;&#x5BF9;&#x8C61;</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>deploymentInformer<span class="token punctuation">)</span> <span class="token function">Lister</span><span class="token punctuation">(</span><span class="token punctuation">)</span> v1<span class="token punctuation">.</span>DeploymentLister <span class="token punctuation">{</span>
<span class="token keyword">return</span> v1<span class="token punctuation">.</span><span class="token function">NewDeploymentLister</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span><span class="token function">Informer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetIndexer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<ul>
<li>deploymentInformer&#x7684;defaultInformer&#x65B9;&#x6CD5;&#x5C06;&#x4F1A;&#x521B;&#x5EFA;&#x51FA;&#x4E00;&#x4E2A;shareIndexInformer</li>
</ul>
<pre class="language-"><code class="lang-go"><span class="token comment">// &#x53EF;&#x5148;&#x770B;&#x770B;&#x4E0B;&#x9762;&#x7684;shareIndexInformer&#x7ED3;&#x6784;</span>
<span class="token keyword">func</span> <span class="token function">NewFilteredDeploymentInformer</span><span class="token punctuation">(</span>client kubernetes<span class="token punctuation">.</span>Interface<span class="token punctuation">,</span> namespace <span class="token builtin">string</span><span class="token punctuation">,</span> resyncPeriod time<span class="token punctuation">.</span>Duration<span class="token punctuation">,</span> indexers cache<span class="token punctuation">.</span>Indexers<span class="token punctuation">,</span> tweakListOptions internalinterfaces<span class="token punctuation">.</span>TweakListOptionsFunc<span class="token punctuation">)</span> cache<span class="token punctuation">.</span>SharedIndexInformer <span class="token punctuation">{</span>
<span class="token keyword">return</span> cache<span class="token punctuation">.</span><span class="token function">NewSharedIndexInformer</span><span class="token punctuation">(</span>
<span class="token comment">// &#x5B9A;&#x4E49;&#x5BF9;&#x8C61;&#x7684;ListWatch&#x65B9;&#x6CD5;&#xFF0C;&#x8FD9;&#x91CC;&#x76F4;&#x63A5;&#x7528;&#x7684;&#x662F;clientset&#x4E2D;&#x7684;&#x65B9;&#x6CD5;</span>
<span class="token operator">&amp;</span>cache<span class="token punctuation">.</span>ListWatch<span class="token punctuation">{</span>
ListFunc<span class="token punctuation">:</span> <span class="token keyword">func</span><span class="token punctuation">(</span>options v1<span class="token punctuation">.</span>ListOptions<span class="token punctuation">)</span> <span class="token punctuation">(</span>runtime<span class="token punctuation">.</span>Object<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> tweakListOptions <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token function">tweakListOptions</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>options<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> client<span class="token punctuation">.</span><span class="token function">AppsV1beta1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Deployments</span><span class="token punctuation">(</span>namespace<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">List</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
WatchFunc<span class="token punctuation">:</span> <span class="token keyword">func</span><span class="token punctuation">(</span>options v1<span class="token punctuation">.</span>ListOptions<span class="token punctuation">)</span> <span class="token punctuation">(</span>watch<span class="token punctuation">.</span>Interface<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> tweakListOptions <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token function">tweakListOptions</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>options<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> client<span class="token punctuation">.</span><span class="token function">AppsV1beta1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Deployments</span><span class="token punctuation">(</span>namespace<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Watch</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token operator">&amp;</span>appsv1beta1<span class="token punctuation">.</span>Deployment<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
resyncPeriod<span class="token punctuation">,</span> <span class="token comment">//&#x521B;&#x5EFA;factory&#x662F;&#x6307;&#x5B9A;&#x7684;&#x65F6;&#x95F4;&#xFF0C;&#x5982;30s</span>
indexers<span class="token punctuation">,</span>
<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h3 id="shareindexinformer&#x7ED3;&#x6784;">shareIndexInformer&#x7ED3;&#x6784;</h3>
<blockquote>
<p>indexer&#xFF1A;&#x5E95;&#x5C42;&#x7F13;&#x5B58;&#xFF0C;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x4E00;&#x4E2A;map&#x8BB0;&#x5F55;&#x5BF9;&#x8C61;&#xFF0C;&#x518D;&#x901A;&#x8FC7;&#x4E00;&#x4E9B;&#x5176;&#x4ED6;map&#x5728;&#x63D2;&#x5165;&#x5220;&#x9664;&#x5BF9;&#x8C61;&#x662F;&#x6839;&#x636E;&#x7D22;&#x5F15;&#x51FD;&#x6570;&#x7EF4;&#x62A4;&#x7D22;&#x5F15;key&#x5982;ns&#x4E0E;&#x5BF9;&#x8C61;pod&#x7684;&#x5173;&#x7CFB;
controller&#xFF1A;informer&#x5185;&#x90E8;&#x7684;&#x4E00;&#x4E2A;controller&#xFF0C;&#x8FD9;&#x4E2A;controller&#x5305;&#x542B;reflector&#xFF1A;&#x6839;&#x636E;&#x7528;&#x6237;&#x5B9A;&#x4E49;&#x7684;ListWatch&#x65B9;&#x6CD5;&#x83B7;&#x53D6;&#x5BF9;&#x8C61;&#x5E76;&#x66F4;&#x65B0;&#x589E;&#x91CF;&#x961F;&#x5217;DeltaFIFO
processor&#xFF1A;&#x77E5;&#x9053;&#x5982;&#x4F55;&#x5904;&#x7406;DeltaFIFO&#x961F;&#x5217;&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x5B9E;&#x73B0;&#x662F;sharedProcessor{}
listerWatcher&#xFF1A;&#x77E5;&#x9053;&#x5982;&#x4F55;list&#x5BF9;&#x8C61;&#x548C;watch&#x5BF9;&#x8C61;&#x7684;&#x65B9;&#x6CD5;
objectType&#xFF1A;deployment{}
resyncCheckPeriod: &#x7ED9;&#x81EA;&#x5DF1;&#x7684;controller&#x7684;reflector&#x6BCF;&#x9694;&#x591A;&#x5C11;s&lt;&#x5C1D;&#x8BD5;&gt;&#x8C03;&#x7528;listener&#x7684;shouldResync&#x65B9;&#x6CD5;
defaultEventHandlerResyncPeriod&#xFF1A;&#x901A;&#x8FC7;AddEventHandler&#x65B9;&#x6CD5;&#x7ED9;informer&#x914D;&#x7F6E;&#x56DE;&#x8C03;&#x65F6;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x914D;&#x7F6E;&#x7684;&#x9ED8;&#x8BA4;&#x503C;&#xFF0C;&#x8FD9;&#x4E2A;&#x503C;&#x7528;&#x5728;processor&#x7684;listener&#x4E2D;&#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;&#x8FDB;&#x884C;resync&#xFF0C;&#x6700;&#x5C0F;1s</p>
</blockquote>
<p>&#x4E24;&#x4E2A;&#x5B57;&#x6BB5;&#x7684;&#x9ED8;&#x8BA4;&#x503C;&#x90FD;&#x662F;&#x6765;&#x81EA;&#x521B;&#x5EFA;factory&#x65F6;&#x6307;&#x5B9A;&#x7684;defaultResync&#xFF0C;&#x5F53;resyncPeriod &lt; s.resyncCheckPeriod&#x65F6;&#xFF0C;&#x5982;&#x679C;informer&#x5DF2;&#x7ECF;&#x542F;&#x52A8;&#x4E86;&#x624D;&#x6DFB;&#x52A0;&#x7684;EventHandler&#xFF0C;&#x90A3;&#x4E48;&#x8C03;&#x6574;resyncPeriod&#x4E3A;resyncCheckPeriod&#xFF0C;&#x5426;&#x5219;&#x8C03;&#x6574;resyncCheckPeriod&#x4E3A;resyncPeriod</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">type</span> sharedIndexInformer <span class="token keyword">struct</span> <span class="token punctuation">{</span>
indexer Indexer <span class="token comment">//informer&#x4E2D;&#x7684;&#x5E95;&#x5C42;&#x7F13;&#x5B58;cache</span>
controller Controller <span class="token comment">//&#x6301;&#x6709;reflector&#x548C;deltaFIFO&#x5BF9;&#x8C61;&#xFF0C;reflector&#x5BF9;&#x8C61;&#x5C06;&#x4F1A;listWatch&#x5BF9;&#x8C61;&#x6DFB;&#x52A0;&#x5230;deltaFIFO&#xFF0C;&#x540C;&#x65F6;&#x66F4;&#x65B0;indexer cahce&#xFF0C;&#x66F4;&#x65B0;&#x6210;&#x529F;&#x5219;&#x901A;&#x8FC7;sharedProcessor&#x89E6;&#x53D1;&#x7528;&#x6237;&#x914D;&#x7F6E;&#x7684;Eventhandler</span>
processor <span class="token operator">*</span>sharedProcessor <span class="token comment">//&#x6301;&#x6709;&#x4E00;&#x7CFB;&#x5217;&#x7684;listener&#xFF0C;&#x6BCF;&#x4E2A;listener&#x5BF9;&#x5E94;&#x7528;&#x6237;&#x7684;EventHandler</span>
cacheMutationDetector MutationDetector <span class="token comment">//&#x53EF;&#x4EE5;&#x5148;&#x5FFD;&#x7565;&#xFF0C;&#x8FD9;&#x4E2A;&#x5BF9;&#x8C61;&#x53EF;&#x4EE5;&#x7528;&#x6765;&#x76D1;&#x6D4B;local cache&#x662F;&#x5426;&#x88AB;&#x5916;&#x90E8;&#x76F4;&#x63A5;&#x4FEE;&#x6539;</span>
<span class="token comment">// This block is tracked to handle late initialization of the controller</span>
listerWatcher ListerWatcher <span class="token comment">//deployment&#x7684;listWatch&#x65B9;&#x6CD5;</span>
objectType runtime<span class="token punctuation">.</span>Object
<span class="token comment">// resyncCheckPeriod is how often we want the reflector&apos;s resync timer to fire so it can call</span>
<span class="token comment">// shouldResync to check if any of our listeners need a resync.</span>
resyncCheckPeriod time<span class="token punctuation">.</span>Duration
<span class="token comment">// defaultEventHandlerResyncPeriod is the default resync period for any handlers added via</span>
<span class="token comment">// AddEventHandler (i.e. they don&apos;t specify one and just want to use the shared informer&apos;s default</span>
<span class="token comment">// value).</span>
defaultEventHandlerResyncPeriod time<span class="token punctuation">.</span>Duration
<span class="token comment">// clock allows for testability</span>
clock clock<span class="token punctuation">.</span>Clock
started<span class="token punctuation">,</span> stopped <span class="token builtin">bool</span>
startedLock sync<span class="token punctuation">.</span>Mutex
<span class="token comment">// blockDeltas gives a way to stop all event distribution so that a late event handler</span>
<span class="token comment">// can safely join the shared informer.</span>
blockDeltas sync<span class="token punctuation">.</span>Mutex
<span class="token punctuation">}</span>
</code></pre>
<p>sharedIndexInformer&#x5BF9;&#x8C61;&#x7684;&#x5173;&#x952E;&#x65B9;&#x6CD5;&#xFF1A;</p>
<h4 id="sharedindexinformer&#x7684;run&#x65B9;&#x6CD5;">sharedIndexInformer&#x7684;Run&#x65B9;&#x6CD5;</h4>
<p>&#x524D;&#x9762;factory&#x7684;start&#x65B9;&#x6CD5;&#x5C31;&#x662F;&#x8C03;&#x7528;&#x4E86;&#x8FD9;&#x4E2A;Run&#x65B9;&#x6CD5;</p>
<p>&#x8BE5;&#x65B9;&#x6CD5;&#x521D;&#x59CB;&#x5316;&#x4E86;controller&#x5BF9;&#x8C61;&#x5E76;&#x542F;&#x52A8;&#xFF0C;&#x540C;&#x65F6;&#x8C03;&#x7528;processor.run&#x542F;&#x52A8;&#x6240;&#x6709;&#x7684;listener&#xFF0C;&#x7528;&#x4E8E;&#x56DE;&#x8C03;&#x7528;&#x6237;&#x914D;&#x7F6E;&#x7684;EventHandler</p>
<blockquote>
<p>&#x5177;&#x4F53;sharedIndexInformer&#x4E2D;&#x7684;processor&#x4E2D;&#x7684;listener&#x662F;&#x600E;&#x4E48;&#x6DFB;&#x52A0;&#x7684;&#xFF0C;&#x770B;&#x4E0B;&#x6587;shareProcessor&#x7684;&#x5206;&#x6790;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>s <span class="token operator">*</span>sharedIndexInformer<span class="token punctuation">)</span> <span class="token function">Run</span><span class="token punctuation">(</span>stopCh <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">defer</span> utilruntime<span class="token punctuation">.</span><span class="token function">HandleCrash</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">//&#x521B;&#x5EFA;&#x4E00;&#x4E2A;DeltaFIFO&#xFF0C;&#x7528;&#x4E8E;shareIndexInformer.controller.reflector</span>
<span class="token comment">//&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8FD9;&#x91CC;&#x628A;indexer&#x5373;&#x672C;&#x5730;&#x7F13;&#x5B58;&#x4F20;&#x5165;&#xFF0C;&#x7528;&#x6765;&#x521D;&#x59CB;&#x5316;deltaFIFO&#x7684;knownObject&#x5B57;&#x6BB5;</span>
fifo <span class="token operator">:=</span> <span class="token function">NewDeltaFIFO</span><span class="token punctuation">(</span>MetaNamespaceKeyFunc<span class="token punctuation">,</span> s<span class="token punctuation">.</span>indexer<span class="token punctuation">)</span>
<span class="token comment">//shareIndexInformer&#x4E2D;&#x7684;controller&#x7684;&#x914D;&#x7F6E;</span>
cfg <span class="token operator">:=</span> <span class="token operator">&amp;</span>Config<span class="token punctuation">{</span>
Queue<span class="token punctuation">:</span> fifo<span class="token punctuation">,</span>
ListerWatcher<span class="token punctuation">:</span> s<span class="token punctuation">.</span>listerWatcher<span class="token punctuation">,</span>
ObjectType<span class="token punctuation">:</span> s<span class="token punctuation">.</span>objectType<span class="token punctuation">,</span>
FullResyncPeriod<span class="token punctuation">:</span> s<span class="token punctuation">.</span>resyncCheckPeriod<span class="token punctuation">,</span>
RetryOnError<span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
ShouldResync<span class="token punctuation">:</span> s<span class="token punctuation">.</span>processor<span class="token punctuation">.</span>shouldResync<span class="token punctuation">,</span> <span class="token comment">// &#x8FD9;&#x4E2A;shouldResync&#x65B9;&#x6CD5;&#x5C06;&#x88AB;&#x7528;&#x5728;reflector ListAndWatch&#x65B9;&#x6CD5;&#x4E2D;&#x5224;&#x65AD;&#x5B9A;&#x65F6;&#x65F6;&#x95F4;resyncCheckPeriod&#x5230;&#x4E86;&#x4E4B;&#x540E;&#x8BE5;&#x4E0D;&#x8BE5;&#x8FDB;&#x884C;resync&#x52A8;&#x4F5C;</span>
<span class="token comment">//&#x4E00;&#x4E2A;&#x77E5;&#x9053;&#x5982;&#x4F55;&#x5904;&#x7406;&#x4ECE;informer&#x4E2D;&#x7684;controller&#x4E2D;&#x7684;deltaFIFO pop&#x51FA;&#x6765;&#x7684;&#x5BF9;&#x8C61;&#x7684;&#x65B9;&#x6CD5;</span>
Process<span class="token punctuation">:</span> s<span class="token punctuation">.</span>HandleDeltas<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
s<span class="token punctuation">.</span>startedLock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> s<span class="token punctuation">.</span>startedLock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// &#x8FD9;&#x91CC;New&#x4E00;&#x4E2A;&#x5177;&#x4F53;&#x7684;controller</span>
s<span class="token punctuation">.</span>controller <span class="token operator">=</span> <span class="token function">New</span><span class="token punctuation">(</span>cfg<span class="token punctuation">)</span>
s<span class="token punctuation">.</span>controller<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token operator">*</span>controller<span class="token punctuation">)</span><span class="token punctuation">.</span>clock <span class="token operator">=</span> s<span class="token punctuation">.</span>clock
s<span class="token punctuation">.</span>started <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// Separate stop channel because Processor should be stopped strictly after controller</span>
processorStopCh <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">var</span> wg wait<span class="token punctuation">.</span>Group
<span class="token keyword">defer</span> wg<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// Wait for Processor to stop</span>
<span class="token keyword">defer</span> <span class="token function">close</span><span class="token punctuation">(</span>processorStopCh<span class="token punctuation">)</span> <span class="token comment">// Tell Processor to stop</span>
<span class="token comment">// &#x8C03;&#x7528;processor.run&#x542F;&#x52A8;&#x6240;&#x6709;&#x7684;listener&#xFF0C;&#x56DE;&#x8C03;&#x7528;&#x6237;&#x914D;&#x7F6E;&#x7684;EventHandler</span>
wg<span class="token punctuation">.</span><span class="token function">StartWithChannel</span><span class="token punctuation">(</span>processorStopCh<span class="token punctuation">,</span> s<span class="token punctuation">.</span>processor<span class="token punctuation">.</span>run<span class="token punctuation">)</span>
<span class="token comment">// &#x542F;&#x52A8;controller</span>
s<span class="token punctuation">.</span>controller<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>stopCh<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x4E3A;shareindexinformer&#x521B;&#x5EFA;controller">&#x4E3A;shareIndexInformer&#x521B;&#x5EFA;controller</h4>
<p>&#x521B;&#x5EFA;Controller&#x7684;New&#x65B9;&#x6CD5;&#x4F1A;&#x751F;&#x6210;&#x4E00;&#x4E2A;controller&#x5BF9;&#x8C61;&#xFF0C;&#x53EA;&#x521D;&#x59CB;&#x5316;controller&#x7684;config&#x6210;&#x5458;&#xFF0C;controller&#x7684;reflector&#x6210;&#x5458;&#x662F;&#x5728;Run&#x7684;&#x65F6;&#x5019;&#x521D;&#x59CB;&#x5316;&#xFF1A;</p>
<ul>
<li><p>&#x901A;&#x8FC7;&#x6267;&#x884C;reflector.Run&#x65B9;&#x6CD5;&#x542F;&#x52A8;reflector&#xFF0C;&#x5F00;&#x542F;&#x5BF9;&#x6307;&#x5B9A;&#x5BF9;&#x8C61;&#x7684;listAndWatch&#x8FC7;&#x7A0B;&#xFF0C;&#x83B7;&#x53D6;&#x7684;&#x5BF9;&#x8C61;&#x5C06;&#x6DFB;&#x52A0;&#x5230;reflector&#x7684;deltaFIFO&#x4E2D;</p>
</li>
<li><p>&#x901A;&#x8FC7;&#x4E0D;&#x65AD;&#x6267;&#x884C;processLoop&#x65B9;&#x6CD5;&#xFF0C;&#x4ECE;DeltaFIFO pop&#x51FA;&#x5BF9;&#x8C61;&#xFF0C;&#x518D;&#x8C03;&#x7528;reflector&#x7684;Process&#xFF08;&#x5C31;&#x662F;shareIndexInformer&#x7684;HandleDeltas&#x65B9;&#x6CD5;&#xFF09;&#x5904;&#x7406;</p>
</li>
</ul>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token function">New</span><span class="token punctuation">(</span>c <span class="token operator">*</span>Config<span class="token punctuation">)</span> Controller <span class="token punctuation">{</span>
ctlr <span class="token operator">:=</span> <span class="token operator">&amp;</span>controller<span class="token punctuation">{</span>
config<span class="token punctuation">:</span> <span class="token operator">*</span>c<span class="token punctuation">,</span>
clock<span class="token punctuation">:</span> <span class="token operator">&amp;</span>clock<span class="token punctuation">.</span>RealClock<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> ctlr
<span class="token punctuation">}</span>
<span class="token comment">//&#x66F4;&#x591A;&#x5B57;&#x6BB5;&#x7684;&#x914D;&#x7F6E;&#x662F;&#x5728;Run&#x7684;&#x65F6;&#x5019;</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>c <span class="token operator">*</span>controller<span class="token punctuation">)</span> <span class="token function">Run</span><span class="token punctuation">(</span>stopCh <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x4F7F;&#x7528;config&#x521B;&#x5EFA;&#x4E00;&#x4E2A;Reflector</span>
r <span class="token operator">:=</span> <span class="token function">NewReflector</span><span class="token punctuation">(</span>
c<span class="token punctuation">.</span>config<span class="token punctuation">.</span>ListerWatcher<span class="token punctuation">,</span> <span class="token comment">// deployment&#x7684;listWatch&#x65B9;&#x6CD5;</span>
c<span class="token punctuation">.</span>config<span class="token punctuation">.</span>ObjectType<span class="token punctuation">,</span> <span class="token comment">// deployment{}</span>
c<span class="token punctuation">.</span>config<span class="token punctuation">.</span>Queue<span class="token punctuation">,</span> <span class="token comment">//DeltaFIFO</span>
c<span class="token punctuation">.</span>config<span class="token punctuation">.</span>FullResyncPeriod<span class="token punctuation">,</span> <span class="token comment">//30s</span>
<span class="token punctuation">)</span>
r<span class="token punctuation">.</span>ShouldResync <span class="token operator">=</span> c<span class="token punctuation">.</span>config<span class="token punctuation">.</span>ShouldResync <span class="token comment">//&#x6765;&#x81EA;sharedProcessor&#x7684;&#x65B9;&#x6CD5;</span>
r<span class="token punctuation">.</span>clock <span class="token operator">=</span> c<span class="token punctuation">.</span>clock
c<span class="token punctuation">.</span>reflectorMutex<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
c<span class="token punctuation">.</span>reflector <span class="token operator">=</span> r
c<span class="token punctuation">.</span>reflectorMutex<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">var</span> wg wait<span class="token punctuation">.</span>Group
<span class="token keyword">defer</span> wg<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// &#x542F;&#x52A8;reflector&#xFF0C;&#x6267;&#x884C;ListWatch&#x65B9;&#x6CD5;</span>
wg<span class="token punctuation">.</span><span class="token function">StartWithChannel</span><span class="token punctuation">(</span>stopCh<span class="token punctuation">,</span> r<span class="token punctuation">.</span>Run<span class="token punctuation">)</span>
<span class="token comment">// &#x4E0D;&#x65AD;&#x6267;&#x884C;processLoop&#xFF0C;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x4ECE;DeltaFIFO pop&#x51FA;&#x5BF9;&#x8C61;&#xFF0C;&#x518D;&#x8C03;&#x7528;reflector&#x7684;Process&#xFF08;&#x5176;&#x5B9E;&#x662F;shareIndexInformer&#x7684;HandleDeltas&#x65B9;&#x6CD5;&#xFF09;&#x5904;&#x7406;</span>
wait<span class="token punctuation">.</span><span class="token function">Until</span><span class="token punctuation">(</span>c<span class="token punctuation">.</span>processLoop<span class="token punctuation">,</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span> stopCh<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="controller&#x7684;processloop&#x65B9;&#x6CD5;">controller&#x7684;processLoop&#x65B9;&#x6CD5;</h4>
<p>&#x4E0D;&#x65AD;&#x6267;&#x884C;processLoop&#xFF0C;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x4ECE;DeltaFIFO pop&#x51FA;&#x5BF9;&#x8C61;&#xFF0C;&#x518D;&#x8C03;&#x7528;reflector&#x7684;Process&#xFF08;&#x5176;&#x5B9E;&#x662F;shareIndexInformer&#x7684;HandleDeltas&#x65B9;&#x6CD5;&#xFF09;&#x5904;&#x7406;</p>
<pre class="language-"><code>func (c *controller) processLoop() {
for {
obj, err := c.config.Queue.Pop(PopProcessFunc(c.config.Process))
if err != nil {
if err == ErrFIFOClosed {
return
}
if c.config.RetryOnError {
// This is the safe way to re-enqueue.
c.config.Queue.AddIfNotPresent(obj)
}
}
}
}
</code></pre><h4 id="deltafifo-pop&#x51FA;&#x6765;&#x7684;&#x5BF9;&#x8C61;&#x5904;&#x7406;&#x903B;&#x8F91;">deltaFIFO pop&#x51FA;&#x6765;&#x7684;&#x5BF9;&#x8C61;&#x5904;&#x7406;&#x903B;&#x8F91;</h4>
<p>&#x5148;&#x770B;&#x770B;controller&#x600E;&#x4E48;&#x5904;&#x7406;DeltaFIFO&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x9700;&#x8981;&#x6CE8;&#x610F;DeltaFIFO&#x4E2D;&#x7684;Deltas&#x7684;&#x7ED3;&#x6784;&#xFF0C;&#x662F;&#x4E00;&#x4E2A;slice&#xFF0C;&#x4FDD;&#x5B58;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;&#x6240;&#x6709;&#x589E;&#x91CF;&#x4E8B;&#x4EF6;</p>
<figure id="fig9.5.1.2"><a href="https://github.com/jianlongzhou/client-go-source-analysis/blob/main/deltaFIFO.png?raw=true" data-lightbox="705eea5b-2724-40bd-a4e3-1780f65ac655" data-title="image" target="_blank"><img src="https://github.com/jianlongzhou/client-go-source-analysis/blob/main/deltaFIFO.png?raw=true" alt="image"></a><figcaption>&#x56FE; 9.5.1.2&#xFF1A;image</figcaption></figure>
<p>sharedIndexInformer&#x7684;HandleDeltas&#x5904;&#x7406;&#x4ECE;deltaFIFO pod&#x51FA;&#x6765;&#x7684;&#x589E;&#x91CF;&#x65F6;&#xFF0C;&#x5148;&#x5C1D;&#x8BD5;&#x66F4;&#x65B0;&#x5230;&#x672C;&#x5730;&#x7F13;&#x5B58;cache&#xFF0C;&#x66F4;&#x65B0;&#x6210;&#x529F;&#x7684;&#x8BDD;&#x4F1A;&#x8C03;&#x7528;processor.distribute&#x65B9;&#x6CD5;&#x5411;processor&#x4E2D;&#x7684;listener&#x6DFB;&#x52A0;notification&#xFF0C;listener&#x542F;&#x52A8;&#x4E4B;&#x540E;&#x4F1A;&#x4E0D;&#x65AD;&#x83B7;&#x53D6;notification&#x56DE;&#x8C03;&#x7528;&#x6237;&#x7684;EventHandler&#x65B9;&#x6CD5;</p>
<ul>
<li>Sync: reflector list&#x5230;&#x5BF9;&#x8C61;&#x65F6;Replace&#x5230;deltaFIFO&#x65F6;daltaType&#x4E3A;Sync&#x6216;&#x8005;resync&#x628A;localstrore&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#x52A0;&#x56DE;&#x5230;deltaFIFO</li>
<li>Added&#x3001;Updated: reflector watch&#x5230;&#x5BF9;&#x8C61;&#x65F6;&#x6839;&#x636E;watch event type&#x662F;Add&#x8FD8;&#x662F;Modify&#x5BF9;&#x5E94;deltaType&#x4E3A;Added&#x6216;&#x8005;Updated</li>
<li><p>Deleted: reflector watch&#x5230;&#x5BF9;&#x8C61;&#x7684;watch event type&#x662F;Delete&#x6216;&#x8005;re-list Replace&#x5230;deltaFIFO&#x65F6;local store&#x591A;&#x51FA;&#x7684;&#x5BF9;&#x8C61;&#x4EE5;Delete&#x7684;&#x65B9;&#x5F0F;&#x52A0;&#x5165;deltaFIFO</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>s <span class="token operator">*</span>sharedIndexInformer<span class="token punctuation">)</span> <span class="token function">HandleDeltas</span><span class="token punctuation">(</span>obj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
s<span class="token punctuation">.</span>blockDeltas<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> s<span class="token punctuation">.</span>blockDeltas<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// from oldest to newest</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> d <span class="token operator">:=</span> <span class="token keyword">range</span> obj<span class="token punctuation">.</span><span class="token punctuation">(</span>Deltas<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">switch</span> d<span class="token punctuation">.</span>Type <span class="token punctuation">{</span>
<span class="token keyword">case</span> Sync<span class="token punctuation">,</span> Added<span class="token punctuation">,</span> Updated<span class="token punctuation">:</span>
isSync <span class="token operator">:=</span> d<span class="token punctuation">.</span>Type <span class="token operator">==</span> Sync
<span class="token comment">// &#x5BF9;&#x8C61;&#x5148;&#x901A;&#x8FC7;shareIndexInformer&#x4E2D;&#x7684;indexer&#x66F4;&#x65B0;&#x5230;&#x7F13;&#x5B58;</span>
<span class="token keyword">if</span> old<span class="token punctuation">,</span> exists<span class="token punctuation">,</span> err <span class="token operator">:=</span> s<span class="token punctuation">.</span>indexer<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>Object<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token operator">&amp;&amp;</span> exists <span class="token punctuation">{</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> s<span class="token punctuation">.</span>indexer<span class="token punctuation">.</span><span class="token function">Update</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>Object<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
<span class="token comment">// &#x5982;&#x679C;informer&#x7684;&#x672C;&#x5730;&#x7F13;&#x5B58;&#x66F4;&#x65B0;&#x6210;&#x529F;&#xFF0C;&#x90A3;&#x4E48;&#x5C31;&#x8C03;&#x7528;shareProcess&#x5206;&#x53D1;&#x5BF9;&#x8C61;&#x7ED9;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x4E49;controller&#x5904;&#x7406;</span>
<span class="token comment">// &#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5BF9;EventHandler&#x6765;&#x8BF4;&#xFF0C;&#x672C;&#x5730;&#x7F13;&#x5B58;&#x5DF2;&#x7ECF;&#x5B58;&#x5728;&#x8BE5;&#x5BF9;&#x8C61;&#x5C31;&#x8BA4;&#x4E3A;&#x662F;update</span>
s<span class="token punctuation">.</span>processor<span class="token punctuation">.</span><span class="token function">distribute</span><span class="token punctuation">(</span>updateNotification<span class="token punctuation">{</span>oldObj<span class="token punctuation">:</span> old<span class="token punctuation">,</span> newObj<span class="token punctuation">:</span> d<span class="token punctuation">.</span>Object<span class="token punctuation">}</span><span class="token punctuation">,</span> isSync<span class="token punctuation">)</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> s<span class="token punctuation">.</span>indexer<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>Object<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
s<span class="token punctuation">.</span>processor<span class="token punctuation">.</span><span class="token function">distribute</span><span class="token punctuation">(</span>addNotification<span class="token punctuation">{</span>newObj<span class="token punctuation">:</span> d<span class="token punctuation">.</span>Object<span class="token punctuation">}</span><span class="token punctuation">,</span> isSync<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">case</span> Deleted<span class="token punctuation">:</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> s<span class="token punctuation">.</span>indexer<span class="token punctuation">.</span><span class="token function">Delete</span><span class="token punctuation">(</span>d<span class="token punctuation">.</span>Object<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
s<span class="token punctuation">.</span>processor<span class="token punctuation">.</span><span class="token function">distribute</span><span class="token punctuation">(</span>deleteNotification<span class="token punctuation">{</span>oldObj<span class="token punctuation">:</span> d<span class="token punctuation">.</span>Object<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
</li>
</ul>
<p>&#x524D;&#x9762;&#x63CF;&#x8FF0;&#x4E86;shareIndexInformer&#x5185;&#x90E8;&#x5982;&#x4F55;&#x4ECE;deltaFIFO&#x53D6;&#x51FA;&#x5BF9;&#x8C61;&#x66F4;&#x65B0;&#x7F13;&#x5B58;&#x5E76;&#x901A;&#x8FC7;processor&#x56DE;&#x8C03;&#x7528;&#x6237;&#x7684;EventHandler&#xFF0C;&#x90A3;deltaFIFO&#x4E2D;&#x7684;&#x589E;&#x91CF;&#x4E8B;&#x4EF6;&#x662F;&#x600E;&#x4E48;&#x52A0;&#x8FDB;&#x5165;&#x7684;&#x5462;&#xFF1F;&#x5148;&#x770B;&#x770B;shareIndexInformer&#x4E2D;controller&#x4E2D;&#x7684;reflector&#x5B9E;&#x73B0;</p>
<h4 id="reflectorrun&#x53D1;&#x8D77;listwatch">reflector.run&#x53D1;&#x8D77;ListWatch</h4>
<p>reflector.run&#x5C06;&#x4F1A;&#x8C03;&#x7528;&#x6307;&#x5B9A;&#x8D44;&#x6E90;&#x7684;ListAndWatch&#x65B9;&#x6CD5;&#xFF0C;&#x6CE8;&#x610F;&#x8FD9;&#x91CC;&#x4EC0;&#x4E48;&#x65F6;&#x5019;&#x53EF;&#x80FD;&#x53D1;&#x751F;re-list&#x6216;&#x8005;re-watch&#xFF1A;&#x56E0;&#x4E3A;&#x662F;&#x901A;&#x8FC7;wait.Util&#x4E0D;&#x65AD;&#x8C03;&#x7528;ListAndWatch&#x65B9;&#x6CD5;&#xFF0C;&#x6240;&#x4EE5;&#x53EA;&#x8981;&#x8BE5;&#x65B9;&#x6CD5;return&#x4E86;&#xFF0C;&#x90A3;&#x4E48;&#x5C31;&#x4F1A;&#x53D1;&#x751F;re-list&#xFF0C;watch&#x8FC7;&#x7A0B;&#x5219;&#x88AB;&#x5D4C;&#x5957;&#x5728;for&#x5FAA;&#x73AF;&#x4E2D;</p>
<ul>
<li>&#x4EE5;ResourceVersion=0&#x5F00;&#x59CB;&#x9996;&#x6B21;&#x7684;List&#x64CD;&#x4F5C;&#x83B7;&#x53D6;&#x6307;&#x5B9A;&#x8D44;&#x6E90;&#x7684;&#x5168;&#x91CF;&#x5BF9;&#x8C61;&#xFF0C;&#x5E76;&#x901A;&#x8FC7;reflector&#x7684;syncWith&#x65B9;&#x6CD5;&#x5C06;&#x6240;&#x6709;&#x5BF9;&#x8C61;&#x6279;&#x91CF;&#x63D2;&#x5165;deltaFIFO</li>
<li>List&#x5B8C;&#x6210;&#x4E4B;&#x540E;&#x5C06;&#x4F1A;&#x66F4;&#x65B0;ResourceVersion&#x7528;&#x6237;Watch&#x64CD;&#x4F5C;&#xFF0C;&#x901A;&#x8FC7;reflector&#x7684;watchHandler&#x65B9;&#x6CD5;&#x628A;watch&#x5230;&#x7684;&#x589E;&#x91CF;&#x5BF9;&#x8C61;&#x52A0;&#x5165;&#x5230;deltaFIFO</li>
</ul>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>r <span class="token operator">*</span>Reflector<span class="token punctuation">)</span> <span class="token function">ListAndWatch</span><span class="token punctuation">(</span>stopCh <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x4EE5;&#x7248;&#x672C;&#x53F7;ResourceVersion=0&#x5F00;&#x59CB;&#x9996;&#x6B21;list</span>
options <span class="token operator">:=</span> metav1<span class="token punctuation">.</span>ListOptions<span class="token punctuation">{</span>ResourceVersion<span class="token punctuation">:</span> <span class="token string">&quot;0&quot;</span><span class="token punctuation">}</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
initTrace <span class="token operator">:=</span> trace<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">&quot;Reflector ListAndWatch&quot;</span><span class="token punctuation">,</span> trace<span class="token punctuation">.</span>Field<span class="token punctuation">{</span><span class="token string">&quot;name&quot;</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">var</span> list runtime<span class="token punctuation">.</span>Object
<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x83B7;&#x53D6;list&#x7684;&#x7ED3;&#x679C;</span>
list<span class="token punctuation">,</span> err <span class="token operator">=</span> pager<span class="token punctuation">.</span><span class="token function">List</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">Background</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> options<span class="token punctuation">)</span>
<span class="token function">close</span><span class="token punctuation">(</span>listCh<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
listMetaInterface<span class="token punctuation">,</span> err <span class="token operator">:=</span> meta<span class="token punctuation">.</span><span class="token function">ListAccessor</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span>
<span class="token comment">// &#x6839;&#x636E;&#x7ED3;&#x679C;&#x66F4;&#x65B0;&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x7528;&#x4E8E;&#x63A5;&#x4E0B;&#x6765;&#x7684;watch</span>
resourceVersion <span class="token operator">=</span> listMetaInterface<span class="token punctuation">.</span><span class="token function">GetResourceVersion</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
items<span class="token punctuation">,</span> err <span class="token operator">:=</span> meta<span class="token punctuation">.</span><span class="token function">ExtractList</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span>
<span class="token comment">// &#x8FD9;&#x91CC;&#x7684;syncWith&#x662F;&#x628A;&#x9996;&#x6B21;list&#x5230;&#x7684;&#x7ED3;&#x679C;&#x901A;&#x8FC7;DeltaFIFO&#x7684;Replce&#x65B9;&#x6CD5;&#x6279;&#x91CF;&#x6DFB;&#x52A0;&#x5230;&#x961F;&#x5217;</span>
<span class="token comment">// &#x961F;&#x5217;&#x63D0;&#x4F9B;&#x4E86;Resync&#x65B9;&#x6CD5;&#x7528;&#x4E8E;&#x5224;&#x65AD;Replace&#x6279;&#x91CF;&#x63D2;&#x5165;&#x7684;&#x5BF9;&#x8C61;&#x662F;&#x5426;&#x90FD;pop&#x51FA;&#x53BB;&#x4E86;&#xFF0C;factory/informer&#x7684;WaitForCacheSync&#x5C31;&#x662F;&#x8C03;&#x7528;&#x4E86;DeltaFIFO&#x7684;&#x7684;Resync&#x65B9;&#x6CD5;</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> r<span class="token punctuation">.</span><span class="token function">syncWith</span><span class="token punctuation">(</span>items<span class="token punctuation">,</span> resourceVersion<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;%s: Unable to sync list result: %v&quot;</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>name<span class="token punctuation">,</span> err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
r<span class="token punctuation">.</span><span class="token function">setLastSyncResourceVersion</span><span class="token punctuation">(</span>resourceVersion<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
<span class="token comment">// &#x4EE5;list&#x5BF9;&#x8C61;&#x4E2D;&#x83B7;&#x53D6;&#x7684;ResourceVersion&#x4E0D;&#x65AD;watch</span>
<span class="token keyword">for</span> <span class="token punctuation">{</span>
start <span class="token operator">:=</span> r<span class="token punctuation">.</span>clock<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
w<span class="token punctuation">,</span> err <span class="token operator">:=</span> r<span class="token punctuation">.</span>listerWatcher<span class="token punctuation">.</span><span class="token function">Watch</span><span class="token punctuation">(</span>options<span class="token punctuation">)</span>
<span class="token comment">// watchhandler&#x5904;&#x7406;watch&#x5230;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x5373;&#x628A;&#x5BF9;&#x8C61;&#x6839;&#x636E;watch.type&#x589E;&#x52A0;&#x5230;DeltaFIFO&#x4E2D;</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> r<span class="token punctuation">.</span><span class="token function">watchHandler</span><span class="token punctuation">(</span>start<span class="token punctuation">,</span> w<span class="token punctuation">,</span> <span class="token operator">&amp;</span>resourceVersion<span class="token punctuation">,</span> resyncerrc<span class="token punctuation">,</span> stopCh<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> errorStopRequested <span class="token punctuation">{</span>
<span class="token keyword">switch</span> <span class="token punctuation">{</span>
<span class="token keyword">case</span> apierrs<span class="token punctuation">.</span><span class="token function">IsResourceExpired</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">:</span>
klog<span class="token punctuation">.</span><span class="token function">V</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Infof</span><span class="token punctuation">(</span><span class="token string">&quot;%s: watch of %v ended with: %v&quot;</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>name<span class="token punctuation">,</span> r<span class="token punctuation">.</span>expectedType<span class="token punctuation">,</span> err<span class="token punctuation">)</span>
<span class="token keyword">default</span><span class="token punctuation">:</span>
klog<span class="token punctuation">.</span><span class="token function">Warningf</span><span class="token punctuation">(</span><span class="token string">&quot;%s: watch of %v ended with: %v&quot;</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>name<span class="token punctuation">,</span> r<span class="token punctuation">.</span>expectedType<span class="token punctuation">,</span> err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h5 id="list&#x51FA;&#x7684;&#x5BF9;&#x8C61;&#x6279;&#x91CF;&#x63D2;&#x5165;deltafifo">list&#x51FA;&#x7684;&#x5BF9;&#x8C61;&#x6279;&#x91CF;&#x63D2;&#x5165;deltaFIFO</h5>
<blockquote>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x662F;syncWith&#x65B9;&#x6CD5;&#x662F;&#x901A;&#x8FC7;&#x8C03;&#x7528;deltaFIFO&#x7684;Replace&#x5B9E;&#x73B0;&#x6279;&#x91CF;&#x63D2;&#x5165;&#xFF0C;&#x5177;&#x4F53;&#x5B9E;&#x73B0;&#x89C1;&#x4E0B;&#x6587;&#x4E2D;deltaFIFO&#x7684;&#x5B9E;&#x73B0;&#x63CF;&#x8FF0;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>r <span class="token operator">*</span>Reflector<span class="token punctuation">)</span> <span class="token function">syncWith</span><span class="token punctuation">(</span>items <span class="token punctuation">[</span><span class="token punctuation">]</span>runtime<span class="token punctuation">.</span>Object<span class="token punctuation">,</span> resourceVersion <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
found <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>items<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> item <span class="token operator">:=</span> <span class="token keyword">range</span> items <span class="token punctuation">{</span>
found <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>found<span class="token punctuation">,</span> item<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> r<span class="token punctuation">.</span>store<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span>found<span class="token punctuation">,</span> resourceVersion<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h5 id="watch&#x51FA;&#x7684;&#x589E;&#x91CF;&#x5BF9;&#x8C61;&#x63D2;&#x5165;&#x5230;deltafifo">watch&#x51FA;&#x7684;&#x589E;&#x91CF;&#x5BF9;&#x8C61;&#x63D2;&#x5165;&#x5230;deltaFIFO</h5>
<blockquote>
<p>watch&#x5230;&#x7684;&#x5BF9;&#x8C61;&#x76F4;&#x63A5;&#x6839;&#x636E;watch&#x5230;&#x7684;&#x4E8B;&#x4EF6;&#x7C7B;&#x578B;eventType&#x66F4;&#x65B0;store&#xFF08;&#x5373;deltaFIFO&#xFF09;&#xFF0C;&#x6CE8;&#x610F;&#x8FD9;&#x4E2A;event&#x662F;api&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x7684;&#xFF0C;watch event type&#x53EF;&#x80FD;&#x662F;Added&#x3001;Modifyed&#x3001;Deleted</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token comment">// watchHandler watches w and keeps *resourceVersion up to date.</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>r <span class="token operator">*</span>Reflector<span class="token punctuation">)</span> <span class="token function">watchHandler</span><span class="token punctuation">(</span>start time<span class="token punctuation">.</span>Time<span class="token punctuation">,</span> w watch<span class="token punctuation">.</span>Interface<span class="token punctuation">,</span> resourceVersion <span class="token operator">*</span><span class="token builtin">string</span><span class="token punctuation">,</span> errc <span class="token keyword">chan</span> <span class="token builtin">error</span><span class="token punctuation">,</span> stopCh <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
<span class="token keyword">for</span> <span class="token punctuation">{</span>
<span class="token keyword">select</span> <span class="token punctuation">{</span>
<span class="token keyword">case</span> <span class="token operator">&lt;-</span>stopCh<span class="token punctuation">:</span>
<span class="token keyword">return</span> errorStopRequested
<span class="token keyword">case</span> err <span class="token operator">:=</span> <span class="token operator">&lt;-</span>errc<span class="token punctuation">:</span>
<span class="token keyword">return</span> err
<span class="token keyword">case</span> event<span class="token punctuation">,</span> ok <span class="token operator">:=</span> <span class="token operator">&lt;-</span>w<span class="token punctuation">.</span><span class="token function">ResultChan</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
<span class="token keyword">switch</span> event<span class="token punctuation">.</span>Type <span class="token punctuation">{</span>
<span class="token keyword">case</span> watch<span class="token punctuation">.</span>Added<span class="token punctuation">:</span>
err <span class="token operator">:=</span> r<span class="token punctuation">.</span>store<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>Object<span class="token punctuation">)</span>
<span class="token keyword">case</span> watch<span class="token punctuation">.</span>Modified<span class="token punctuation">:</span>
err <span class="token operator">:=</span> r<span class="token punctuation">.</span>store<span class="token punctuation">.</span><span class="token function">Update</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>Object<span class="token punctuation">)</span>
<span class="token keyword">case</span> watch<span class="token punctuation">.</span>Deleted<span class="token punctuation">:</span>
err <span class="token operator">:=</span> r<span class="token punctuation">.</span>store<span class="token punctuation">.</span><span class="token function">Delete</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>Object<span class="token punctuation">)</span>
<span class="token keyword">case</span> watch<span class="token punctuation">.</span>Bookmark<span class="token punctuation">:</span>
<span class="token comment">// A `Bookmark` means watch has synced here, just update the resourceVersion</span>
<span class="token keyword">default</span><span class="token punctuation">:</span>
utilruntime<span class="token punctuation">.</span><span class="token function">HandleError</span><span class="token punctuation">(</span>fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;%s: unable to understand watch event %#v&quot;</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>name<span class="token punctuation">,</span> event<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token operator">*</span>resourceVersion <span class="token operator">=</span> newResourceVersion
r<span class="token punctuation">.</span><span class="token function">setLastSyncResourceVersion</span><span class="token punctuation">(</span>newResourceVersion<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h5 id="&#x5B9A;&#x65F6;&#x89E6;&#x53D1;resync">&#x5B9A;&#x65F6;&#x89E6;&#x53D1;resync</h5>
<p>&#x5728;ListAndWatch&#x4E2D;&#x8FD8;&#x8D77;&#x4E86;&#x4E00;&#x4E2A;gorouting&#x5B9A;&#x65F6;&#x7684;&#x8FDB;&#x884C;resync&#x52A8;&#x4F5C;</p>
<pre class="language-"><code class="lang-go"> resyncerrc <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token builtin">error</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>
cancelCh <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> <span class="token function">close</span><span class="token punctuation">(</span>cancelCh<span class="token punctuation">)</span>
<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//&#x83B7;&#x53D6;&#x4E00;&#x4E2A;&#x5B9A;&#x65F6;channel&#xFF0C;&#x5B9A;&#x65F6;&#x7684;&#x65F6;&#x95F4;&#x662F;&#x521B;&#x5EFA;informer factory&#x65F6;&#x4F20;&#x5165;&#x7684;resyncPeriod</span>
resyncCh<span class="token punctuation">,</span> cleanup <span class="token operator">:=</span> r<span class="token punctuation">.</span><span class="token function">resyncChan</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">cleanup</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// Call the last one written into cleanup</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token punctuation">{</span>
<span class="token keyword">select</span> <span class="token punctuation">{</span>
<span class="token keyword">case</span> <span class="token operator">&lt;-</span>resyncCh<span class="token punctuation">:</span>
<span class="token keyword">case</span> <span class="token operator">&lt;-</span>stopCh<span class="token punctuation">:</span>
<span class="token keyword">return</span>
<span class="token keyword">case</span> <span class="token operator">&lt;-</span>cancelCh<span class="token punctuation">:</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> r<span class="token punctuation">.</span>ShouldResync <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token operator">||</span> r<span class="token punctuation">.</span><span class="token function">ShouldResync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
klog<span class="token punctuation">.</span><span class="token function">V</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Infof</span><span class="token punctuation">(</span><span class="token string">&quot;%s: forcing resync&quot;</span><span class="token punctuation">,</span> r<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> r<span class="token punctuation">.</span>store<span class="token punctuation">.</span><span class="token function">Resync</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
resyncerrc <span class="token operator">&lt;-</span> err
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token function">cleanup</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
resyncCh<span class="token punctuation">,</span> cleanup <span class="token operator">=</span> r<span class="token punctuation">.</span><span class="token function">resyncChan</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre>
<p>&#x8C03;&#x7528;deltaFIFO&#x7684;Resync&#x65B9;&#x6CD5;&#xFF0C;&#x628A;&#x5E95;&#x5C42;&#x7F13;&#x5B58;&#x7684;&#x5BF9;&#x8C61;&#x5168;&#x90E8;&#x91CD;&#x65B0;&#x6DFB;&#x52A0;&#x5230;deltaFIFO&#x4E2D;</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">Resync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> f<span class="token punctuation">.</span>knownObjects <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
keys <span class="token operator">:=</span> f<span class="token punctuation">.</span>knownObjects<span class="token punctuation">.</span><span class="token function">ListKeys</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> k <span class="token operator">:=</span> <span class="token keyword">range</span> keys <span class="token punctuation">{</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">syncKeyLocked</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x9700;&#x8981;&#x6CE8;&#x610F;&#x7684;&#x662F;&#xFF0C;&#x5728;&#x6DFB;&#x52A0;&#x5BF9;&#x8C61;&#x5230;deltaFIFO&#x65F6;&#x4F1A;&#x68C0;&#x67E5;&#x8BE5;&#x961F;&#x5217;&#x4E2D;&#x6709;&#x6CA1;&#x6709;&#x589E;&#x91CF;&#x6CA1;&#x6709;&#x5904;&#x7406;&#x5B8C;&#x7684;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x5219;&#x5FFD;&#x7565;&#x8FD9;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;&#x6B64;&#x6B21;resync</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">syncKeyLocked</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
obj<span class="token punctuation">,</span> exists<span class="token punctuation">,</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span>knownObjects<span class="token punctuation">.</span><span class="token function">GetByKey</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
klog<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;Unexpected error %v during lookup of key %v, unable to queue object for sync&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">,</span> key<span class="token punctuation">)</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token operator">!</span>exists <span class="token punctuation">{</span>
klog<span class="token punctuation">.</span><span class="token function">Infof</span><span class="token punctuation">(</span><span class="token string">&quot;Key %v does not exist in known objects store, unable to queue object for sync&quot;</span><span class="token punctuation">,</span> key<span class="token punctuation">)</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token comment">// If we are doing Resync() and there is already an event queued for that object,</span>
<span class="token comment">// we ignore the Resync for it. This is to avoid the race, in which the resync</span>
<span class="token comment">// comes with the previous value of object (since queueing an event for the object</span>
<span class="token comment">// doesn&apos;t trigger changing the underlying store &lt;knownObjects&gt;.</span>
id<span class="token punctuation">,</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">KeyOf</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> KeyError<span class="token punctuation">{</span>obj<span class="token punctuation">,</span> err<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x5982;&#x679C;deltaFIFO&#x4E2D;&#x8BE5;&#x5BF9;&#x8C61;&#x8FD8;&#x6709;&#x589E;&#x91CF;&#x6CA1;&#x6709;&#x5904;&#x7406;&#xFF0C;&#x5219;&#x5FFD;&#x7565;&#x4EE5;&#x907F;&#x514D;&#x51B2;&#x7A81;&#xFF0C;&#x539F;&#x56E0;&#x5982;&#x4E0A;&#x9762;&#x6CE8;&#x91CA;&#xFF1A;&#x5728;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;&#x589E;&#x91CF;&#x5217;&#x8868;&#x4E2D;&#xFF0C;&#x6392;&#x5728;&#x540E;&#x9762;&#x7684;&#x589E;&#x91CF;&#x7684;object&#x76F8;&#x6BD4;&#x524D;&#x9762;&#x7684;&#x589E;&#x91CF;&#x5E94;&#x8BE5;&#x66F4;&#x65B0;&#x624D;&#x662F;&#x5408;&#x7406;&#x7684;</span>
<span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>items<span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x8DDF;deltaFIFO&#x7684;Replace&#x65B9;&#x6CD5;&#x4E00;&#x6837;&#xFF0C;&#x90FD;&#x662F;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;Sync&#x7C7B;&#x578B;&#x7684;&#x589E;&#x91CF;</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">queueActionLocked</span><span class="token punctuation">(</span>Sync<span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;couldn&apos;t queue object: %v&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<h3 id="&#x5E95;&#x5C42;&#x7F13;&#x5B58;&#x7684;&#x5B9E;&#x73B0;">&#x5E95;&#x5C42;&#x7F13;&#x5B58;&#x7684;&#x5B9E;&#x73B0;</h3>
<p>shareIndexInformer&#x4E2D;&#x5E26;&#x6709;&#x4E00;&#x4E2A;&#x7F13;&#x5B58;indexer&#xFF0C;&#x662F;&#x4E00;&#x4E2A;&#x652F;&#x6301;&#x7D22;&#x5F15;&#x7684;map&#xFF0C;&#x4F18;&#x70B9;&#x662F;&#x652F;&#x6301;&#x5FEB;&#x901F;&#x67E5;&#x8BE2;&#xFF1A;</p>
<ul>
<li>Indexer&#x3001;Queue&#x63A5;&#x53E3;&#x548C;cache&#x7ED3;&#x6784;&#x4F53;&#x90FD;&#x5B9E;&#x73B0;&#x4E86;&#x9876;&#x5C42;&#x7684;Store&#x63A5;&#x53E3;</li>
<li>cache&#x7ED3;&#x6784;&#x4F53;&#x6301;&#x6709;threadSafeStore&#x5BF9;&#x8C61;&#xFF0C;threadSafeStore&#x662F;&#x7EBF;&#x7A0B;&#x5B89;&#x5168;&#x7684;&#xFF0C;&#x5E76;&#x4E14;&#x5177;&#x5907;&#x81EA;&#x5B9A;&#x4E49;&#x7D22;&#x5F15;&#x67E5;&#x627E;&#x7684;&#x80FD;&#x529B;</li>
</ul>
<p>threadSafeMap&#x7684;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#xFF1A;</p>
<blockquote>
<p>items:&#x5B58;&#x50A8;&#x5177;&#x4F53;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x6BD4;&#x5982;key&#x4E3A;ns/podName&#xFF0C;value&#x4E3A;pod{}
Indexers:&#x4E00;&#x4E2A;map[string]IndexFunc&#x7ED3;&#x6784;&#xFF0C;&#x5176;&#x4E2D;key&#x4E3A;&#x7D22;&#x5F15;&#x7684;&#x540D;&#x79F0;&#xFF0C;&#x5982;&#x2019;namespace&#x2019;&#x5B57;&#x7B26;&#x4E32;&#xFF0C;value&#x5219;&#x662F;&#x4E00;&#x4E2A;&#x5177;&#x4F53;&#x7684;&#x7D22;&#x5F15;&#x51FD;&#x6570;
Indices:&#x4E00;&#x4E2A;map[string]Index&#x7ED3;&#x6784;&#xFF0C;&#x5176;&#x4E2D;key&#x4E5F;&#x662F;&#x7D22;&#x5F15;&#x7684;&#x540D;&#x79F0;&#xFF0C;value&#x662F;&#x4E00;&#x4E2A;map[string]sets.String&#x7ED3;&#x6784;&#xFF0C;&#x5176;&#x4E2D;key&#x662F;&#x5177;&#x4F53;&#x7684;namespace&#xFF0C;&#x5982;default&#x8FD9;&#x4E2A;ns&#xFF0C;vlaue&#x5219;&#x662F;&#x8FD9;&#x4E2A;ns&#x4E0B;&#x7684;&#x6309;&#x7167;&#x7D22;&#x5F15;&#x51FD;&#x6570;&#x6C42;&#x51FA;&#x6765;&#x7684;&#x503C;&#x7684;&#x96C6;&#x5408;&#xFF0C;&#x6BD4;&#x5982;default&#x8FD9;&#x4E2A;ns&#x4E0B;&#x7684;&#x6240;&#x6709;pod&#x5BF9;&#x8C61;&#x540D;&#x79F0;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">type</span> threadSafeMap <span class="token keyword">struct</span> <span class="token punctuation">{</span>
lock sync<span class="token punctuation">.</span>RWMutex
items <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">// indexers maps a name to an IndexFunc</span>
indexers Indexers
<span class="token comment">// indices maps a name to an Index</span>
indices Indices
<span class="token punctuation">}</span>
<span class="token comment">// Indexers maps a name to a IndexFunc</span>
<span class="token keyword">type</span> Indexers <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>IndexFunc
<span class="token comment">// Indices maps a name to an Index</span>
<span class="token keyword">type</span> Indices <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>Index
<span class="token keyword">type</span> Index <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>sets<span class="token punctuation">.</span>String
</code></pre>
<h4 id="&#x7D22;&#x5F15;&#x7684;&#x7EF4;&#x62A4;">&#x7D22;&#x5F15;&#x7684;&#x7EF4;&#x62A4;</h4>
<p>&#x901A;&#x8FC7;&#x5728;&#x5411;items&#x63D2;&#x5165;&#x5BF9;&#x8C61;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x904D;&#x5386;&#x6240;&#x6709;&#x7684;Indexers&#x4E2D;&#x7684;&#x7D22;&#x5F15;&#x51FD;&#x6570;&#xFF0C;&#x6839;&#x636E;&#x7D22;&#x5F15;&#x51FD;&#x6570;&#x5B58;&#x50A8;&#x7D22;&#x5F15;key&#x5230;value&#x7684;&#x96C6;&#x5408;&#x5173;&#x7CFB;&#xFF0C;&#x4EE5;&#x4E0B;&#x56FE;&#x5F0F;&#x7ED3;&#x6784;&#x53EF;&#x4EE5;&#x5F88;&#x597D;&#x7684;&#x8BF4;&#x660E;&#xFF1A;</p>
<figure id="fig9.5.1.3"><a href="https://user-images.githubusercontent.com/41672087/116666278-5981ca00-a9cd-11eb-9570-8ee6eb447d05.png" data-lightbox="7cabd09e-b8cf-4f03-89ef-634096028d13" data-title="&#x56FE;&#x7247;&#x6765;&#x6E90;&#x4E8E;&#x7F51;&#x7EDC;" target="_blank"><img src="https://user-images.githubusercontent.com/41672087/116666278-5981ca00-a9cd-11eb-9570-8ee6eb447d05.png" alt="&#x56FE;&#x7247;&#x6765;&#x6E90;&#x4E8E;&#x7F51;&#x7EDC;"></a><figcaption>&#x56FE; 9.5.1.3&#xFF1A;&#x56FE;&#x7247;&#x6765;&#x6E90;&#x4E8E;&#x7F51;&#x7EDC;</figcaption></figure>
<h4 id="&#x7F13;&#x5B58;&#x4E2D;&#x589E;&#x52A0;&#x5BF9;&#x8C61;">&#x7F13;&#x5B58;&#x4E2D;&#x589E;&#x52A0;&#x5BF9;&#x8C61;</h4>
<p>&#x5728;&#x5411;threadSafeMap&#x7684;items map&#x4E2D;&#x589E;&#x52A0;&#x5B8C;&#x5BF9;&#x8C61;&#x540E;&#xFF0C;&#x518D;&#x901A;&#x8FC7;updateIndices&#x66F4;&#x65B0;&#x7D22;&#x5F15;&#x7ED3;&#x6784;</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>c <span class="token operator">*</span>threadSafeMap<span class="token punctuation">)</span> <span class="token function">Add</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">,</span> obj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
c<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> c<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
oldObject <span class="token operator">:=</span> c<span class="token punctuation">.</span>items<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
<span class="token comment">//&#x5B58;&#x50A8;&#x5BF9;&#x8C61;</span>
c<span class="token punctuation">.</span>items<span class="token punctuation">[</span>key<span class="token punctuation">]</span> <span class="token operator">=</span> obj
<span class="token comment">//&#x66F4;&#x65B0;&#x7D22;&#x5F15;</span>
c<span class="token punctuation">.</span><span class="token function">updateIndices</span><span class="token punctuation">(</span>oldObject<span class="token punctuation">,</span> obj<span class="token punctuation">,</span> key<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// updateIndices modifies the objects location in the managed indexes, if this is an update, you must provide an oldObj</span>
<span class="token comment">// updateIndices must be called from a function that already has a lock on the cache</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>c <span class="token operator">*</span>threadSafeMap<span class="token punctuation">)</span> <span class="token function">updateIndices</span><span class="token punctuation">(</span>oldObj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> newObj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> key <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// if we got an old object, we need to remove it before we add it again</span>
<span class="token keyword">if</span> oldObj <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x66F4;&#x65B0;&#x64CD;&#x4F5C;&#xFF0C;&#x5148;&#x5220;&#x9664;&#x539F;&#x5BF9;&#x8C61;&#x7684;&#x7D22;&#x5F15;&#x8BB0;&#x5F55;</span>
c<span class="token punctuation">.</span><span class="token function">deleteFromIndices</span><span class="token punctuation">(</span>oldObj<span class="token punctuation">,</span> key<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x679A;&#x4E3E;&#x6240;&#x6709;&#x6DFB;&#x52A0;&#x7684;&#x7D22;&#x5F15;&#x51FD;&#x6570;</span>
<span class="token keyword">for</span> name<span class="token punctuation">,</span> indexFunc <span class="token operator">:=</span> <span class="token keyword">range</span> c<span class="token punctuation">.</span>indexers <span class="token punctuation">{</span>
<span class="token comment">//&#x6839;&#x636E;&#x7D22;&#x5F15;&#x51FD;&#x6570;&#x8BA1;&#x7B97;obj&#x5BF9;&#x5E94;&#x7684;</span>
indexValues<span class="token punctuation">,</span> err <span class="token operator">:=</span> <span class="token function">indexFunc</span><span class="token punctuation">(</span>newObj<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token function">panic</span><span class="token punctuation">(</span>fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;unable to calculate an index entry for key %q on index %q: %v&quot;</span><span class="token punctuation">,</span> key<span class="token punctuation">,</span> name<span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
index <span class="token operator">:=</span> c<span class="token punctuation">.</span>indices<span class="token punctuation">[</span>name<span class="token punctuation">]</span>
<span class="token keyword">if</span> index <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
index <span class="token operator">=</span> Index<span class="token punctuation">{</span><span class="token punctuation">}</span>
c<span class="token punctuation">.</span>indices<span class="token punctuation">[</span>name<span class="token punctuation">]</span> <span class="token operator">=</span> index
<span class="token punctuation">}</span>
<span class="token comment">//&#x7D22;&#x5F15;&#x51FD;&#x6570;&#x8BA1;&#x7B97;&#x51FA;&#x591A;&#x4E2A;value&#xFF0C;&#x4E5F;&#x53EF;&#x80FD;&#x662F;&#x4E00;&#x4E2A;&#xFF0C;&#x6BD4;&#x5982;pod&#x7684;ns&#x5C31;&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x503C;&#xFF0C;pod&#x7684;label&#x53EF;&#x80FD;&#x5C31;&#x6709;&#x591A;&#x4E2A;&#x503C;</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> indexValue <span class="token operator">:=</span> <span class="token keyword">range</span> indexValues <span class="token punctuation">{</span>
<span class="token comment">//&#x6BD4;&#x5982;namespace&#x7D22;&#x5F15;&#xFF0C;&#x6839;&#x636E;indexValue=default&#xFF0C;&#x83B7;&#x53D6;default&#x5BF9;&#x5E94;&#x7684;ji he&#x518D;&#x628A;&#x5F53;&#x524D;&#x5BF9;&#x8C61;&#x63D2;&#x5165;</span>
set <span class="token operator">:=</span> index<span class="token punctuation">[</span>indexValue<span class="token punctuation">]</span>
<span class="token keyword">if</span> set <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
set <span class="token operator">=</span> sets<span class="token punctuation">.</span>String<span class="token punctuation">{</span><span class="token punctuation">}</span>
index<span class="token punctuation">[</span>indexValue<span class="token punctuation">]</span> <span class="token operator">=</span> set
<span class="token punctuation">}</span>
set<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="indexfunc&#x7D22;&#x5F15;&#x51FD;&#x6570;">IndexFunc&#x7D22;&#x5F15;&#x51FD;&#x6570;</h4>
<p>&#x4E00;&#x4E2A;&#x5178;&#x578B;&#x7684;&#x7D22;&#x5F15;&#x51FD;&#x6570;MetaNamespaceIndexFunc&#xFF0C;&#x65B9;&#x4FBF;&#x67E5;&#x8BE2;&#x65F6;&#x53EF;&#x4EE5;&#x6839;&#x636E;namespace&#x83B7;&#x53D6;&#x8BE5;namespace&#x4E0B;&#x7684;&#x6240;&#x6709;&#x5BF9;&#x8C61;</p>
<pre class="language-"><code class="lang-go"><span class="token comment">// MetaNamespaceIndexFunc is a default index function that indexes based on an object&apos;s namespace</span>
<span class="token keyword">func</span> <span class="token function">MetaNamespaceIndexFunc</span><span class="token punctuation">(</span>obj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
meta<span class="token punctuation">,</span> err <span class="token operator">:=</span> meta<span class="token punctuation">.</span><span class="token function">Accessor</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">&quot;&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span> fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;object has no meta: %v&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span>meta<span class="token punctuation">.</span><span class="token function">GetNamespace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="index&#x65B9;&#x6CD5;&#x5229;&#x7528;&#x7D22;&#x5F15;&#x67E5;&#x627E;&#x5BF9;&#x8C61;">Index&#x65B9;&#x6CD5;&#x5229;&#x7528;&#x7D22;&#x5F15;&#x67E5;&#x627E;&#x5BF9;&#x8C61;</h4>
<p>&#x63D0;&#x4F9B;&#x5229;&#x7528;&#x7D22;&#x5F15;&#x6765;&#x67E5;&#x8BE2;&#x7684;&#x80FD;&#x529B;&#xFF0C;Index&#x65B9;&#x6CD5;&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x7D22;&#x5F15;&#x540D;&#x79F0;&#x548C;&#x5BF9;&#x8C61;&#xFF0C;&#x67E5;&#x8BE2;&#x6240;&#x6709;&#x7684;&#x5173;&#x8054;&#x5BF9;&#x8C61;</p>
<blockquote>
<p>&#x4F8B;&#x5982;&#x901A;&#x8FC7; <code>Index(&#x201C;namespace&#x201D;, &amp;metav1.ObjectMeta{Namespace: namespace})</code>&#x83B7;&#x53D6;&#x6307;&#x5B9A;ns&#x4E0B;&#x7684;&#x6240;&#x6709;&#x5BF9;&#x8C61;&#xFF0C;&#x5177;&#x4F53;&#x53EF;&#x4EE5;&#x53C2;&#x8003;tools/cache/listers.go#ListAllByNamespace</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>c <span class="token operator">*</span>threadSafeMap<span class="token punctuation">)</span> <span class="token function">Index</span><span class="token punctuation">(</span>indexName <span class="token builtin">string</span><span class="token punctuation">,</span> obj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
c<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">RLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> c<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">RUnlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
indexFunc <span class="token operator">:=</span> c<span class="token punctuation">.</span>indexers<span class="token punctuation">[</span>indexName<span class="token punctuation">]</span>
<span class="token keyword">if</span> indexFunc <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;Index with name %s does not exist&quot;</span><span class="token punctuation">,</span> indexName<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
indexKeys<span class="token punctuation">,</span> err <span class="token operator">:=</span> <span class="token function">indexFunc</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
<span class="token punctuation">}</span>
index <span class="token operator">:=</span> c<span class="token punctuation">.</span>indices<span class="token punctuation">[</span>indexName<span class="token punctuation">]</span>
<span class="token keyword">var</span> returnKeySet sets<span class="token punctuation">.</span>String
<span class="token comment">//&#x4F8B;&#x5982;namespace&#x7D22;&#x5F15;</span>
<span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>indexKeys<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">1</span> <span class="token punctuation">{</span>
<span class="token comment">// In majority of cases, there is exactly one value matching.</span>
<span class="token comment">// Optimize the most common path - deduping is not needed here.</span>
returnKeySet <span class="token operator">=</span> index<span class="token punctuation">[</span>indexKeys<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">]</span>
<span class="token comment">//&#x4F8B;&#x5982;label&#x7D22;&#x5F15;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token comment">// Need to de-dupe the return list.</span>
<span class="token comment">// Since multiple keys are allowed, this can happen.</span>
returnKeySet <span class="token operator">=</span> sets<span class="token punctuation">.</span>String<span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> indexKey <span class="token operator">:=</span> <span class="token keyword">range</span> indexKeys <span class="token punctuation">{</span>
<span class="token keyword">for</span> key <span class="token operator">:=</span> <span class="token keyword">range</span> index<span class="token punctuation">[</span>indexKey<span class="token punctuation">]</span> <span class="token punctuation">{</span>
returnKeySet<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
list <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> returnKeySet<span class="token punctuation">.</span><span class="token function">Len</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> absoluteKey <span class="token operator">:=</span> <span class="token keyword">range</span> returnKeySet <span class="token punctuation">{</span>
list <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>list<span class="token punctuation">,</span> c<span class="token punctuation">.</span>items<span class="token punctuation">[</span>absoluteKey<span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> list<span class="token punctuation">,</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<h3 id="deltafifo&#x5B9E;&#x73B0;">deltaFIFO&#x5B9E;&#x73B0;</h3>
<p>shareIndexInformer.controller.reflector&#x4E2D;&#x7684;deltaFIFO&#x5B9E;&#x73B0;</p>
<blockquote>
<p>items&#xFF1A;&#x8BB0;&#x5F55;deltaFIFO&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x6CE8;&#x610F;map&#x7684;value&#x662F;&#x4E00;&#x4E2A;delta slice
queue&#xFF1A;&#x8BB0;&#x5F55;&#x4E0A;&#x9762;items&#x4E2D;&#x7684;key&#xFF0C;&#x7EF4;&#x62A4;&#x5BF9;&#x8C61;&#x7684;fifo&#x987A;&#x5E8F;
populated&#xFF1A;&#x961F;&#x5217;&#x4E2D;&#x662F;&#x5426;&#x586B;&#x5145;&#x8FC7;&#x6570;&#x636E;&#xFF0C;LIST&#x65F6;&#x8C03;&#x7528;Replace&#x6216;&#x8C03;&#x7528;Delete/Add/Update&#x90FD;&#x4F1A;&#x7F6E;&#x4E3A;true
initialPopulationCount&#xFF1A;&#x9996;&#x6B21;List&#x7684;&#x65F6;&#x5019;&#x83B7;&#x53D6;&#x5230;&#x7684;&#x6570;&#x636E;&#x5C31;&#x4F1A;&#x8C03;&#x7528;Replace&#x6279;&#x91CF;&#x589E;&#x52A0;&#x5230;&#x961F;&#x5217;&#xFF0C;&#x540C;&#x65F6;&#x8BBE;&#x7F6E;initialPopulationCount&#x4E3A;List&#x5230;&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x91CF;&#xFF0C;&#x6BCF;&#x6B21;Pop&#x51FA;&#x6765;&#x4F1A;&#x51CF;&#x4E00;&#xFF0C;&#x7528;&#x4E8E;&#x5224;&#x65AD;&#x662F;&#x5426;&#x628A;&#x9996;&#x6B21;&#x6279;&#x91CF;&#x63D2;&#x5165;&#x7684;&#x6570;&#x636E;&#x90FD;POP&#x51FA;&#x53BB;&#x4E86;
keyFunc&#xFF1A;&#x77E5;&#x9053;&#x600E;&#x4E48;&#x4ECE;&#x5BF9;&#x8C61;&#x4E2D;&#x89E3;&#x6790;&#x51FA;&#x5BF9;&#x5E94;key&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x5982;MetaNamespaceKeyFunc&#x53EF;&#x4EE5;&#x89E3;&#x6790;&#x51FA;namespace/name&#x7684;&#x5F62;&#x5F0F;
knownObjects&#xFF1A;&#x8FD9;&#x4E2A;&#x5176;&#x5B9E;&#x5C31;&#x662F;shareIndexInformer&#x4E2D;&#x7684;indexer&#x5E95;&#x5C42;&#x7F13;&#x5B58;&#x7684;&#x5F15;&#x7528;&#xFF0C;&#x53EF;&#x4EE5;&#x8BA4;&#x4E3A;&#x548C;etcd&#x4E2D;&#x7684;&#x6570;&#x636E;&#x4E00;&#x81F4;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token comment">// NewDeltaFIFO&#x65B9;&#x6CD5;&#x5728;&#x524D;&#x9762;&#x5206;&#x6790;&#x7684;sharedIndexInformer&#x7684;Run&#x65B9;&#x6CD5;&#x4E2D;&#x8C03;&#x7528;</span>
<span class="token comment">// fifo := NewDeltaFIFO(MetaNamespaceKeyFunc, s.indexer)</span>
<span class="token keyword">func</span> <span class="token function">NewDeltaFIFO</span><span class="token punctuation">(</span>keyFunc KeyFunc<span class="token punctuation">,</span> knownObjects KeyListerGetter<span class="token punctuation">)</span> <span class="token operator">*</span>DeltaFIFO <span class="token punctuation">{</span>
f <span class="token operator">:=</span> <span class="token operator">&amp;</span>DeltaFIFO<span class="token punctuation">{</span>
items<span class="token punctuation">:</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>Deltas<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
queue<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
keyFunc<span class="token punctuation">:</span> keyFunc<span class="token punctuation">,</span>
knownObjects<span class="token punctuation">:</span> knownObjects<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
f<span class="token punctuation">.</span>cond<span class="token punctuation">.</span>L <span class="token operator">=</span> <span class="token operator">&amp;</span>f<span class="token punctuation">.</span>lock
<span class="token keyword">return</span> f
<span class="token punctuation">}</span>
<span class="token keyword">type</span> DeltaFIFO <span class="token keyword">struct</span> <span class="token punctuation">{</span>
<span class="token comment">// lock/cond protects access to &apos;items&apos; and &apos;queue&apos;.</span>
lock sync<span class="token punctuation">.</span>RWMutex
cond sync<span class="token punctuation">.</span>Cond
<span class="token comment">// We depend on the property that items in the set are in</span>
<span class="token comment">// the queue and vice versa, and that all Deltas in this</span>
<span class="token comment">// map have at least one Delta.</span>
<span class="token comment">// &#x8FD9;&#x91CC;&#x7684;Deltas&#x662F;[]Delta&#x7C7B;&#x578B;</span>
items <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span>Deltas
queue <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span>
<span class="token comment">// populated is true if the first batch of items inserted by Replace() has been populated</span>
<span class="token comment">// or Delete/Add/Update was called first.</span>
populated <span class="token builtin">bool</span>
<span class="token comment">// initialPopulationCount is the number of items inserted by the first call of Replace()</span>
initialPopulationCount <span class="token builtin">int</span>
<span class="token comment">// keyFunc is used to make the key used for queued item</span>
<span class="token comment">// insertion and retrieval, and should be deterministic.</span>
keyFunc KeyFunc
<span class="token comment">// knownObjects list keys that are &quot;known&quot;, for the</span>
<span class="token comment">// purpose of figuring out which items have been deleted</span>
<span class="token comment">// when Replace() or Delete() is called.</span>
<span class="token comment">// &#x8FD9;&#x4E2A;&#x5176;&#x5B9E;&#x5C31;&#x662F;shareIndexInformer&#x4E2D;&#x7684;indexer&#x5E95;&#x5C42;&#x7F13;&#x5B58;&#x7684;&#x5F15;&#x7528;</span>
knownObjects KeyListerGetter
<span class="token comment">// Indication the queue is closed.</span>
<span class="token comment">// Used to indicate a queue is closed so a control loop can exit when a queue is empty.</span>
<span class="token comment">// Currently, not used to gate any of CRED operations.</span>
closed <span class="token builtin">bool</span>
closedLock sync<span class="token punctuation">.</span>Mutex
<span class="token punctuation">}</span>
<span class="token keyword">type</span> Delta <span class="token keyword">struct</span> <span class="token punctuation">{</span>
Type DeltaType
Object <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// Deltas is a list of one or more &apos;Delta&apos;s to an individual object.</span>
<span class="token comment">// The oldest delta is at index 0, the newest delta is the last one.</span>
<span class="token keyword">type</span> Deltas <span class="token punctuation">[</span><span class="token punctuation">]</span>Delta
</code></pre>
<p>DeltaFIFO&#x5173;&#x952E;&#x7684;&#x65B9;&#x6CD5;&#xFF1A;</p>
<h4 id="&#x5411;deltafifo&#x6279;&#x91CF;&#x63D2;&#x5165;&#x5BF9;&#x8C61;">&#x5411;deltaFIFO&#x6279;&#x91CF;&#x63D2;&#x5165;&#x5BF9;&#x8C61;</h4>
<p>&#x6279;&#x91CF;&#x5411;&#x961F;&#x5217;&#x63D2;&#x5165;&#x6570;&#x636E;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x6CE8;&#x610F;knownObjects&#x662F;informer&#x4E2D;&#x672C;&#x5730;&#x7F13;&#x5B58;indexer&#x7684;&#x5F15;&#x7528;</p>
<p>&#x8FD9;&#x91CC;&#x4F1A;&#x66F4;&#x65B0;deltaFIFO&#x7684;initialPopulationCount&#x4E3A;Replace list&#x7684;&#x5BF9;&#x8C61;&#x603B;&#x6570;&#x52A0;&#x4E0A;list&#x4E2D;&#x76F8;&#x6BD4;knownObjects&#x591A;&#x51FA;&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x91CF;&#x3002;</p>
<blockquote>
<p>&#x56E0;&#x4E3A;Replace&#x65B9;&#x6CD5;&#x53EF;&#x80FD;&#x662F;reflector&#x53D1;&#x751F;re-list&#x7684;&#x65F6;&#x5019;&#x518D;&#x6B21;&#x8C03;&#x7528;&#xFF0C;&#x8FD9;&#x4E2A;&#x65F6;&#x5019;&#x5C31;&#x4F1A;&#x51FA;&#x73B0;knownObjects&#x4E2D;&#x5B58;&#x5728;&#x7684;&#x5BF9;&#x8C61;&#x4E0D;&#x5728;Replace list&#x7684;&#x60C5;&#x51B5;&#xFF08;&#x6BD4;&#x5982;watch&#x7684;delete&#x4E8B;&#x4EF6;&#x4E22;&#x5931;&#x4E86;&#xFF09;&#xFF0C;&#x8FD9;&#x4E2A;&#x65F6;&#x5019;&#x662F;&#x628A;&#x8FD9;&#x4E9B;&#x5BF9;&#x8C61;&#x7B5B;&#x9009;&#x51FA;&#x6765;&#xFF0C;&#x5C01;&#x88C5;&#x6210;DeletedFinalStateUnknown&#x5BF9;&#x8C61;&#x4EE5;Delete type&#x7C7B;&#x578B;&#x518D;&#x6B21;&#x52A0;&#x5165;&#x5230;deltaFIFO&#x4E2D;&#xFF0C;&#x8FD9;&#x6837;&#x6700;&#x7EC8;&#x4ECE;detaFIFO&#x5904;&#x7406;&#x8FD9;&#x4E2A;DeletedFinalStateUnknown &#x589E;&#x91CF;&#x65F6;&#x5C31;&#x53EF;&#x4EE5;&#x66F4;&#x65B0;&#x672C;&#x5730;&#x7F13;&#x5B58;&#x5E76;&#x4E14;&#x89E6;&#x53D1;reconcile&#x3002;
&#x56E0;&#x4E3A;&#x8FD9;&#x4E2A;&#x5BF9;&#x8C61;&#x6700;&#x7EC8;&#x7684;&#x7ED3;&#x6784;&#x786E;&#x5B9E;&#x627E;&#x4E0D;&#x5230;&#x4E86;&#xFF0C;&#x6240;&#x4EE5;&#x53EA;&#x80FD;&#x7528;knownObjects&#x91CC;&#x9762;&#x7684;&#x8BB0;&#x5F55;&#x6765;&#x5C01;&#x88C5;delta&#xFF0C;&#x6240;&#x4EE5;&#x53EB;&#x505A;FinalStateUnknown&#x3002;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">Replace</span><span class="token punctuation">(</span>list <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> resourceVersion <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
keys <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span>sets<span class="token punctuation">.</span>String<span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> item <span class="token operator">:=</span> <span class="token keyword">range</span> list <span class="token punctuation">{</span>
key<span class="token punctuation">,</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">KeyOf</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> KeyError<span class="token punctuation">{</span>item<span class="token punctuation">,</span> err<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
keys<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span>
<span class="token comment">// &#x8C03;&#x7528;deltaFIFO&#x7684;queueActionLocked&#x5411;deltaFIFO&#x589E;&#x52A0;&#x4E00;&#x4E2A;&#x589E;&#x91CF;</span>
<span class="token comment">// &#x53EF;&#x4EE5;&#x770B;&#x5230;Replace&#x6DFB;&#x52A0;&#x7684;Delta type&#x90FD;&#x662F;Sync</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">queueActionLocked</span><span class="token punctuation">(</span>Sync<span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;couldn&apos;t enqueue object: %v&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x5E95;&#x5C42;&#x7684;&#x7F13;&#x5B58;&#x4E0D;&#x5E94;&#x8BE5;&#x4F1A;&#x662F;nil&#xFF0C;&#x53EF;&#x4EE5;&#x5FFD;&#x7565;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;</span>
<span class="token keyword">if</span> f<span class="token punctuation">.</span>knownObjects <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token comment">// Do deletion detection against our own list.</span>
queuedDeletions <span class="token operator">:=</span> <span class="token number">0</span>
<span class="token keyword">for</span> k<span class="token punctuation">,</span> oldItem <span class="token operator">:=</span> <span class="token keyword">range</span> f<span class="token punctuation">.</span>items <span class="token punctuation">{</span>
<span class="token keyword">if</span> keys<span class="token punctuation">.</span><span class="token function">Has</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">continue</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x5F53;knownObjects&#x4E3A;&#x7A7A;&#x65F6;&#xFF0C;&#x5982;&#x679C;item&#x4E2D;&#x5B58;&#x5728;&#x5BF9;&#x8C61;&#x4E0D;&#x5728;&#x65B0;&#x6765;&#x7684;list&#x4E2D;&#xFF0C;&#x90A3;&#x4E48;&#x8BE5;&#x5BF9;&#x8C61;&#x88AB;&#x8BA4;&#x4E3A;&#x8981;&#x88AB;&#x5220;&#x9664;</span>
<span class="token keyword">var</span> deletedObj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">if</span> n <span class="token operator">:=</span> oldItem<span class="token punctuation">.</span><span class="token function">Newest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> n <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
deletedObj <span class="token operator">=</span> n<span class="token punctuation">.</span>Object
<span class="token punctuation">}</span>
queuedDeletions<span class="token operator">++</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">queueActionLocked</span><span class="token punctuation">(</span>Deleted<span class="token punctuation">,</span> DeletedFinalStateUnknown<span class="token punctuation">{</span>k<span class="token punctuation">,</span> deletedObj<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> <span class="token operator">!</span>f<span class="token punctuation">.</span>populated <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>populated <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token comment">// While there shouldn&apos;t be any queued deletions in the initial</span>
<span class="token comment">// population of the queue, it&apos;s better to be on the safe side.</span>
f<span class="token punctuation">.</span>initialPopulationCount <span class="token operator">=</span> <span class="token function">len</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span> <span class="token operator">+</span> queuedDeletions
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token comment">// Detect deletions not already in the queue.</span>
<span class="token comment">// &#x5F53;reflector&#x53D1;&#x751F;re-list&#x65F6;&#xFF0C;&#x53EF;&#x80FD;&#x4F1A;&#x51FA;&#x73B0;knownObjects&#x4E2D;&#x5B58;&#x5728;&#x7684;&#x5BF9;&#x8C61;&#x4E0D;&#x5728;Replace list&#x7684;&#x60C5;&#x51B5;</span>
knownKeys <span class="token operator">:=</span> f<span class="token punctuation">.</span>knownObjects<span class="token punctuation">.</span><span class="token function">ListKeys</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// &#x8BB0;&#x5F55;&#x8FD9;&#x6B21;&#x66FF;&#x6362;&#x76F8;&#x5F53;&#x4E8E;&#x5728;&#x7F13;&#x5B58;&#x4E2D;&#x5220;&#x9664;&#x591A;&#x5C11;&#x5BF9;&#x8C61;</span>
queuedDeletions <span class="token operator">:=</span> <span class="token number">0</span>
<span class="token comment">// &#x679A;&#x4E3E;local store&#x4E2D;&#x7684;&#x6240;&#x6709;&#x5BF9;&#x8C61;</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> k <span class="token operator">:=</span> <span class="token keyword">range</span> knownKeys <span class="token punctuation">{</span>
<span class="token comment">// &#x5BF9;&#x8C61;&#x4E5F;&#x5728;Replace list&#x4E2D;&#xFF0C;&#x6240;&#x4EE5;&#x8DF3;&#x8FC7;</span>
<span class="token keyword">if</span> keys<span class="token punctuation">.</span><span class="token function">Has</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">continue</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x5BF9;&#x8C61;&#x5728;&#x7F13;&#x5B58;&#xFF0C;&#x4F46;&#x4E0D;&#x5728;list&#x4E2D;&#xFF0C;&#x8BF4;&#x660E;&#x66FF;&#x6362;&#x64CD;&#x4F5C;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x8FD9;&#x4E2A;&#x5BF9;&#x8C61;&#x76F8;&#x5F53;&#x4E8E;&#x88AB;&#x5220;&#x9664;&#x4E86;</span>
<span class="token comment">// &#x6CE8;&#x610F;&#x8FD9;&#x91CC;&#x7684;&#x6240;&#x8C13;&#x66FF;&#x6362;&#xFF0C;&#x5BF9;deltaFIFO&#x6765;&#x8BF4;&#xFF0C;&#x662F;&#x7ED9;&#x961F;&#x5217;&#x4E2D;&#x7684;&#x5BF9;&#x5E94;&#x5BF9;&#x8C61;&#x589E;&#x52A0;&#x4E00;&#x4E2A;</span>
<span class="token comment">// delete&#x589E;&#x91CF;queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj})</span>
<span class="token comment">// &#x771F;&#x6B63;&#x5220;&#x9664;&#x7F13;&#x5B58;&#x9700;&#x8981;&#x7B49;&#x5230;DeletedFinalStateUnknown&#x589E;&#x91CF;&#x88AB;POP&#x51FA;&#x6765;&#x64CD;&#x4F5C;local store&#x65F6;</span>
deletedObj<span class="token punctuation">,</span> exists<span class="token punctuation">,</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span>knownObjects<span class="token punctuation">.</span><span class="token function">GetByKey</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span>
queuedDeletions<span class="token operator">++</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">queueActionLocked</span><span class="token punctuation">(</span>Deleted<span class="token punctuation">,</span> DeletedFinalStateUnknown<span class="token punctuation">{</span>k<span class="token punctuation">,</span> deletedObj<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x8BBE;&#x7F6E;f.initialPopulationCount&#xFF0C;&#x8BE5;&#x503C;&#x5927;&#x4E8E;0&#x8868;&#x793A;&#x9996;&#x6B21;&#x63D2;&#x5165;&#x7684;&#x5BF9;&#x8C61;&#x8FD8;&#x6CA1;&#x6709;&#x5168;&#x90E8;pop&#x51FA;&#x53BB;</span>
<span class="token comment">// informer WaitForCacheSync&#x5C31;&#x662F;&#x5728;&#x7B49;&#x5F85;&#x8BE5;&#x503C;&#x4E3A;0</span>
<span class="token keyword">if</span> <span class="token operator">!</span>f<span class="token punctuation">.</span>populated <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>populated <span class="token operator">=</span> <span class="token boolean">true</span>
f<span class="token punctuation">.</span>initialPopulationCount <span class="token operator">=</span> <span class="token function">len</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span> <span class="token operator">+</span> queuedDeletions
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x4ECE;deltafifo-pop&#x51FA;&#x5BF9;&#x8C61;">&#x4ECE;deltaFIFO pop&#x51FA;&#x5BF9;&#x8C61;</h4>
<p>&#x4ECE;&#x961F;&#x5217;&#x4E2D;Pop&#x51FA;&#x4E00;&#x4E2A;&#x65B9;&#x6CD5;&#xFF0C;&#x5E76;&#x7531;&#x51FD;&#x6570;process&#x6765;&#x5904;&#x7406;&#xFF0C;&#x5176;&#x5B9E;&#x5C31;&#x662F;shareIndexInformer&#x7684;HandleDeltas</p>
<blockquote>
<p>&#x6BCF;&#x6B21;&#x4ECE;DeltaFIFO Pop&#x51FA;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF0C;f.initialPopulationCount&#x4F1A;&#x51CF;&#x4E00;&#xFF0C;&#x521D;&#x59CB;&#x503C;&#x4E3A;List&#x65F6;&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x91CF;
&#x524D;&#x9762;&#x7684;Informer&#x7684;WaitForCacheSync&#x6700;&#x7EC8;&#x5C31;&#x662F;&#x8C03;&#x7528;&#x4E86;&#x8FD9;&#x4E2A;HasSynced&#x65B9;&#x6CD5;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">Pop</span><span class="token punctuation">(</span>process PopProcessFunc<span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token punctuation">{</span>
<span class="token keyword">for</span> <span class="token function">len</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>queue<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">{</span>
<span class="token comment">// When the queue is empty, invocation of Pop() is blocked until new item is enqueued.</span>
<span class="token comment">// When Close() is called, the f.closed is set and the condition is broadcasted.</span>
<span class="token comment">// Which causes this loop to continue and return from the Pop().</span>
<span class="token keyword">if</span> f<span class="token punctuation">.</span><span class="token function">IsClosed</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> ErrFIFOClosed
<span class="token punctuation">}</span>
f<span class="token punctuation">.</span>cond<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">//&#x53D6;&#x51FA;&#x961F;&#x9996;&#x5143;&#x7D20;</span>
id <span class="token operator">:=</span> f<span class="token punctuation">.</span>queue<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
<span class="token comment">//&#x53BB;&#x6389;&#x961F;&#x9996;&#x5143;&#x7D20;</span>
f<span class="token punctuation">.</span>queue <span class="token operator">=</span> f<span class="token punctuation">.</span>queue<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token punctuation">]</span>
<span class="token comment">//&#x9996;&#x6B21;&#x586B;&#x5145;&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x51CF;&#x4E00;</span>
<span class="token keyword">if</span> f<span class="token punctuation">.</span>initialPopulationCount <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>initialPopulationCount<span class="token operator">--</span>
<span class="token punctuation">}</span>
item<span class="token punctuation">,</span> ok <span class="token operator">:=</span> f<span class="token punctuation">.</span>items<span class="token punctuation">[</span>id<span class="token punctuation">]</span>
<span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">{</span>
<span class="token comment">// Item may have been deleted subsequently.</span>
<span class="token keyword">continue</span>
<span class="token punctuation">}</span>
<span class="token function">delete</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>items<span class="token punctuation">,</span> id<span class="token punctuation">)</span>
<span class="token comment">//&#x5904;&#x7406;&#x589E;&#x91CF;&#x5BF9;&#x8C61;</span>
err <span class="token operator">:=</span> <span class="token function">process</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span>
<span class="token comment">// &#x5982;&#x679C;&#x6CA1;&#x6709;&#x5904;&#x7406;&#x6210;&#x529F;&#xFF0C;&#x90A3;&#x4E48;&#x5C31;&#x4F1A;&#x91CD;&#x65B0;&#x52A0;&#x5230;deltaFIFO&#x961F;&#x5217;&#x4E2D;</span>
<span class="token keyword">if</span> e<span class="token punctuation">,</span> ok <span class="token operator">:=</span> err<span class="token punctuation">.</span><span class="token punctuation">(</span>ErrRequeue<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span>
f<span class="token punctuation">.</span><span class="token function">addIfNotPresent</span><span class="token punctuation">(</span>id<span class="token punctuation">,</span> item<span class="token punctuation">)</span>
err <span class="token operator">=</span> e<span class="token punctuation">.</span>Err
<span class="token punctuation">}</span>
<span class="token comment">// Don&apos;t need to copyDeltas here, because we&apos;re transferring</span>
<span class="token comment">// ownership to the caller.</span>
<span class="token keyword">return</span> item<span class="token punctuation">,</span> err
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="deltafifo&#x662F;&#x5426;&#x540C;&#x6B65;&#x5B8C;&#x6210;">deltaFIFO&#x662F;&#x5426;&#x540C;&#x6B65;&#x5B8C;&#x6210;</h4>
<p>&#x4E32;&#x8FDE;&#x524D;&#x9762;&#x7684;&#x95EE;&#x9898;&#xFF1A;factory&#x7684;WaitForCacheSync&#x662F;&#x5982;&#x4F55;&#x7B49;&#x5F85;&#x7F13;&#x5B58;&#x540C;&#x6B65;&#x5B8C;&#x6210;</p>
<blockquote>
<p>factory&#x7684;WaitForCacheSync&#x65B9;&#x6CD5;&#x8C03;&#x7528;informer&#x7684;HasSync&#x65B9;&#x6CD5;&#xFF0C;&#x7EE7;&#x800C;&#x8C03;&#x7528;deltaFIFO&#x7684;HasSync&#x65B9;&#x6CD5;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x5224;&#x65AD;&#x4ECE;reflector list&#x5230;&#x7684;&#x6570;&#x636E;&#x662F;&#x5426;pop&#x5B8C;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">HasSynced</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> f<span class="token punctuation">.</span>populated <span class="token operator">&amp;&amp;</span> f<span class="token punctuation">.</span>initialPopulationCount <span class="token operator">==</span> <span class="token number">0</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x540C;&#x6B65;local-store&#x5230;deltafifo">&#x540C;&#x6B65;local store&#x5230;deltaFIFO</h4>
<blockquote>
<p>&#x6240;&#x8C13;&#x7684;resync&#xFF0C;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x628A;knownObjects&#x5373;&#x7F13;&#x5B58;&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#x5168;&#x90E8;&#x518D;&#x901A;&#x8FC7;queueActionLocked(Sync, obj)&#x52A0;&#x5230;&#x961F;&#x5217;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">Resync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> f<span class="token punctuation">.</span>lock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> f<span class="token punctuation">.</span>knownObjects <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
keys <span class="token operator">:=</span> f<span class="token punctuation">.</span>knownObjects<span class="token punctuation">.</span><span class="token function">ListKeys</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// &#x628A;local store&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#x90FD;&#x4EE5;Sync&#x7C7B;&#x578B;&#x589E;&#x91CF;&#x7684;&#x5F62;&#x5F0F;&#x91CD;&#x65B0;&#x653E;&#x56DE;&#x5230;deltaFIFO</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> k <span class="token operator">:=</span> <span class="token keyword">range</span> keys <span class="token punctuation">{</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">syncKeyLocked</span><span class="token punctuation">(</span>k<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> err
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">syncKeyLocked</span><span class="token punctuation">(</span>key <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
obj<span class="token punctuation">,</span> exists<span class="token punctuation">,</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span>knownObjects<span class="token punctuation">.</span><span class="token function">GetByKey</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span>
<span class="token comment">// If we are doing Resync() and there is already an event queued for that object,</span>
<span class="token comment">// we ignore the Resync for it. This is to avoid the race, in which the resync</span>
<span class="token comment">// comes with the previous value of object (since queueing an event for the object</span>
<span class="token comment">// doesn&apos;t trigger changing the underlying store &lt;knownObjects&gt;.</span>
id<span class="token punctuation">,</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">KeyOf</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> KeyError<span class="token punctuation">{</span>obj<span class="token punctuation">,</span> err<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x5982;&#x4E0A;&#x8FF0;&#x6CE8;&#x91CA;&#xFF0C;&#x5728;resync&#x65F6;&#xFF0C;&#x5982;&#x679C;deltaFIFO&#x4E2D;&#x8BE5;&#x5BF9;&#x8C61;&#x8FD8;&#x5B58;&#x5728;&#x5176;&#x4ED6;delta&#x6CA1;&#x5904;&#x7406;&#xFF0C;&#x90A3;&#x4E48;&#x5FFD;&#x7565;&#x8FD9;&#x6B21;&#x7684;resync</span>
<span class="token comment">// &#x56E0;&#x4E3A;&#x8C03;&#x7528;queueActionLocked&#x662F;&#x589E;&#x52A0;delta&#x662F;&#x901A;&#x8FC7;append&#x7684;&#xFF0C;&#x4E14;&#x5904;&#x7406;&#x5BF9;&#x8C61;&#x7684;&#x589E;&#x91CF;delta&#x65F6;&#xFF0C;&#x662F;&#x4ECE;oldest&#x5230;newdest&#x7684;</span>
<span class="token comment">// &#x6240;&#x4EE5;&#x5982;&#x679C;&#x67D0;&#x4E2A;&#x5BF9;&#x8C61;&#x8FD8;&#x5B58;&#x5728;&#x589E;&#x91CF;&#x6CA1;&#x5904;&#x7406;&#xFF0C;&#x518D;append&#x5C31;&#x53EF;&#x80FD;&#x5BFC;&#x81F4;&#x540E;&#x5904;&#x7406;&#x7684;delta&#x662F;&#x65E7;&#x7684;&#x5BF9;&#x8C61;</span>
<span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>items<span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8FD9;&#x91CC;&#x8DDF;list&#x4E00;&#x6837;&#xFF0C;&#x589E;&#x52A0;&#x5230;deltaFIFO&#x7684;&#x662F;&#x4E00;&#x4E2A;Sync&#x7C7B;&#x578B;&#x7684;&#x589E;&#x91CF;</span>
<span class="token keyword">if</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">queueActionLocked</span><span class="token punctuation">(</span>Sync<span class="token punctuation">,</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;couldn&apos;t queue object: %v&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x5728;deltafifo&#x589E;&#x52A0;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;">&#x5728;deltaFIFO&#x589E;&#x52A0;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;</h4>
<p>&#x6CE8;&#x610F;&#x8FD9;&#x91CC;&#x5728;append&#x589E;&#x91CF;&#x65F6;&#x7684;&#x53BB;&#x91CD;&#x903B;&#x8F91;&#xFF1A;&#x5982;&#x679C;&#x8FDE;&#x7EED;&#x7684;&#x4E24;&#x4E2A;&#x589E;&#x91CF;&#x7C7B;&#x578B;&#x90FD;&#x662F;Deleted&#xFF0C;&#x90A3;&#x4E48;&#x5C31;&#x53BB;&#x6389;&#x4E00;&#x4E2A;&#xFF08;&#x6B63;&#x5E38;&#x60C5;&#x51B5;&#x786E;&#x5B9E;&#x4E0D;&#x4F1A;&#x51FA;&#x73B0;&#x8FD9;&#x6837;&#xFF0C;&#x4E14;&#x6CA1;&#x5FC5;&#x8981;&#xFF09;&#xFF0C;&#x4F18;&#x5148;&#x53BB;&#x6389;&#x524D;&#x9762;&#x6240;&#x8BF4;&#x7684;&#x56E0;&#x4E3A;re-list&#x53EF;&#x80FD;&#x5BFC;&#x81F4;&#x7684;api&#x4E0E;local store&#x4E0D;&#x4E00;&#x81F4;&#x800C;&#x589E;&#x52A0;&#x7684;DeletedFinalStateUnknown&#x7C7B;&#x578B;&#x7684;&#x589E;&#x91CF;</p>
<pre class="language-"><code class="lang-go"><span class="token comment">//&#x5728;&#x961F;&#x5217;&#x4E2D;&#x7ED9;&#x6307;&#x5B9A;&#x7684;&#x5BF9;&#x8C61;append&#x4E00;&#x4E2A;Delta</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>f <span class="token operator">*</span>DeltaFIFO<span class="token punctuation">)</span> <span class="token function">queueActionLocked</span><span class="token punctuation">(</span>actionType DeltaType<span class="token punctuation">,</span> obj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
id<span class="token punctuation">,</span> err <span class="token operator">:=</span> f<span class="token punctuation">.</span><span class="token function">KeyOf</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> KeyError<span class="token punctuation">{</span>obj<span class="token punctuation">,</span> err<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// &#x628A;&#x589E;&#x91CF;append&#x5230;slice&#x7684;&#x540E;&#x9762;</span>
newDeltas <span class="token operator">:=</span> <span class="token function">append</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>items<span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token punctuation">,</span> Delta<span class="token punctuation">{</span>actionType<span class="token punctuation">,</span> obj<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// &#x8FDE;&#x7EED;&#x7684;&#x4E24;&#x4E2A;Deleted delta&#x5C06;&#x4F1A;&#x53BB;&#x6389;&#x4E00;&#x4E2A;</span>
newDeltas <span class="token operator">=</span> <span class="token function">dedupDeltas</span><span class="token punctuation">(</span>newDeltas<span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token function">len</span><span class="token punctuation">(</span>newDeltas<span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">0</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x7EF4;&#x62A4;queue&#x961F;&#x5217;</span>
<span class="token keyword">if</span> <span class="token boolean">_</span><span class="token punctuation">,</span> exists <span class="token operator">:=</span> f<span class="token punctuation">.</span>items<span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token operator">!</span>exists <span class="token punctuation">{</span>
f<span class="token punctuation">.</span>queue <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>queue<span class="token punctuation">,</span> id<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
f<span class="token punctuation">.</span>items<span class="token punctuation">[</span>id<span class="token punctuation">]</span> <span class="token operator">=</span> newDeltas
f<span class="token punctuation">.</span>cond<span class="token punctuation">.</span><span class="token function">Broadcast</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token comment">// We need to remove this from our map (extra items in the queue are</span>
<span class="token comment">// ignored if they are not in the map).</span>
<span class="token function">delete</span><span class="token punctuation">(</span>f<span class="token punctuation">.</span>items<span class="token punctuation">,</span> id<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x5F53;&#x524D;&#x8BA4;&#x4E3A;&#x53EA;&#x6709;&#x8FDE;&#x7EED;&#x7684;&#x4E24;&#x4E2A;Delete delta&#x624D;&#x6709;&#x5FC5;&#x8981;&#x53BB;&#x91CD;</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token function">dedupDeltas</span><span class="token punctuation">(</span>deltas Deltas<span class="token punctuation">)</span> Deltas <span class="token punctuation">{</span>
n <span class="token operator">:=</span> <span class="token function">len</span><span class="token punctuation">(</span>deltas<span class="token punctuation">)</span>
<span class="token keyword">if</span> n <span class="token operator">&lt;</span> <span class="token number">2</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> deltas
<span class="token punctuation">}</span>
<span class="token comment">// &#x6BCF;&#x6B21;&#x53D6;&#x6700;&#x540E;&#x4E24;&#x4E2A;delta&#x6765;&#x5224;&#x65AD;</span>
a <span class="token operator">:=</span> <span class="token operator">&amp;</span>deltas<span class="token punctuation">[</span>n<span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span>
b <span class="token operator">:=</span> <span class="token operator">&amp;</span>deltas<span class="token punctuation">[</span>n<span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">]</span>
<span class="token keyword">if</span> out <span class="token operator">:=</span> <span class="token function">isDup</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> out <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
d <span class="token operator">:=</span> <span class="token function">append</span><span class="token punctuation">(</span>Deltas<span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> deltas<span class="token punctuation">[</span><span class="token punctuation">:</span>n<span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token operator">...</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> <span class="token function">append</span><span class="token punctuation">(</span>d<span class="token punctuation">,</span> <span class="token operator">*</span>out<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> deltas
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">isDup</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b <span class="token operator">*</span>Delta<span class="token punctuation">)</span> <span class="token operator">*</span>Delta <span class="token punctuation">{</span>
<span class="token comment">// &#x5F53;&#x524D;&#x8BA4;&#x4E3A;&#x53EA;&#x6709;&#x8FDE;&#x7EED;&#x7684;&#x4E24;&#x4E2A;Delete delta&#x624D;&#x6709;&#x5FC5;&#x8981;&#x53BB;&#x91CD;</span>
<span class="token keyword">if</span> out <span class="token operator">:=</span> <span class="token function">isDeletionDup</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span> out <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> out
<span class="token punctuation">}</span>
<span class="token comment">// TODO: Detect other duplicate situations? Are there any?</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token comment">// keep the one with the most information if both are deletions.</span>
<span class="token keyword">func</span> <span class="token function">isDeletionDup</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b <span class="token operator">*</span>Delta<span class="token punctuation">)</span> <span class="token operator">*</span>Delta <span class="token punctuation">{</span>
<span class="token keyword">if</span> b<span class="token punctuation">.</span>Type <span class="token operator">!=</span> Deleted <span class="token operator">||</span> a<span class="token punctuation">.</span>Type <span class="token operator">!=</span> Deleted <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
<span class="token comment">// Do more sophisticated checks, or is this sufficient?</span>
<span class="token comment">// &#x4F18;&#x5148;&#x53BB;&#x91CD;DeletedFinalStateUnknown&#x7C7B;&#x578B;&#x7684;Deleted delta</span>
<span class="token keyword">if</span> <span class="token boolean">_</span><span class="token punctuation">,</span> ok <span class="token operator">:=</span> b<span class="token punctuation">.</span>Object<span class="token punctuation">.</span><span class="token punctuation">(</span>DeletedFinalStateUnknown<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span>
<span class="token keyword">return</span> a
<span class="token punctuation">}</span>
<span class="token keyword">return</span> b
<span class="token punctuation">}</span>
</code></pre>
<h3 id="sharedprocessor&#x7684;&#x5B9E;&#x73B0;">sharedProcessor&#x7684;&#x5B9E;&#x73B0;</h3>
<p>shareIndexInformer&#x4E2D;&#x7684;sharedProcess&#x7ED3;&#x6784;&#xFF0C;&#x7528;&#x4E8E;&#x5206;&#x53D1;deltaFIFO&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x56DE;&#x8C03;&#x7528;&#x6237;&#x914D;&#x7F6E;&#x7684;EventHandler&#x65B9;&#x6CD5;</p>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;shareIndexInformer&#x4E2D;&#x7684;process&#x76F4;&#x63A5;&#x901A;&#x8FC7;&amp;sharedProcessor{clock: realClock}&#x521D;&#x59CB;&#x5316;</p>
<pre class="language-"><code class="lang-go"><span class="token comment">// NewSharedIndexInformer creates a new instance for the listwatcher.</span>
<span class="token keyword">func</span> <span class="token function">NewSharedIndexInformer</span><span class="token punctuation">(</span>lw ListerWatcher<span class="token punctuation">,</span> objType runtime<span class="token punctuation">.</span>Object<span class="token punctuation">,</span> defaultEventHandlerResyncPeriod time<span class="token punctuation">.</span>Duration<span class="token punctuation">,</span> indexers Indexers<span class="token punctuation">)</span> SharedIndexInformer <span class="token punctuation">{</span>
realClock <span class="token operator">:=</span> <span class="token operator">&amp;</span>clock<span class="token punctuation">.</span>RealClock<span class="token punctuation">{</span><span class="token punctuation">}</span>
sharedIndexInformer <span class="token operator">:=</span> <span class="token operator">&amp;</span>sharedIndexInformer<span class="token punctuation">{</span>
<span class="token comment">// &#x521D;&#x59CB;&#x5316;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x7684;processor</span>
processor<span class="token punctuation">:</span> <span class="token operator">&amp;</span>sharedProcessor<span class="token punctuation">{</span>clock<span class="token punctuation">:</span> realClock<span class="token punctuation">}</span><span class="token punctuation">,</span>
indexer<span class="token punctuation">:</span> <span class="token function">NewIndexer</span><span class="token punctuation">(</span>DeletionHandlingMetaNamespaceKeyFunc<span class="token punctuation">,</span> indexers<span class="token punctuation">)</span><span class="token punctuation">,</span>
listerWatcher<span class="token punctuation">:</span> lw<span class="token punctuation">,</span>
objectType<span class="token punctuation">:</span> objType<span class="token punctuation">,</span>
resyncCheckPeriod<span class="token punctuation">:</span> defaultEventHandlerResyncPeriod<span class="token punctuation">,</span>
defaultEventHandlerResyncPeriod<span class="token punctuation">:</span> defaultEventHandlerResyncPeriod<span class="token punctuation">,</span>
<span class="token comment">// cacheMutationDetector&#xFF1A;&#x53EF;&#x4EE5;&#x8BB0;&#x5F55;local store&#x662F;&#x5426;&#x88AB;&#x5916;&#x90E8;&#x4FEE;&#x6539;</span>
cacheMutationDetector<span class="token punctuation">:</span> <span class="token function">NewCacheMutationDetector</span><span class="token punctuation">(</span>fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">&quot;%T&quot;</span><span class="token punctuation">,</span> objType<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
clock<span class="token punctuation">:</span> realClock<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> sharedIndexInformer
<span class="token punctuation">}</span>
</code></pre>
<p>&#x5982;&#x4E0B;&#x4E3A;sharedProcessor&#x7ED3;&#x6784;&#xFF1A;</p>
<blockquote>
<p>listenersStarted&#xFF1A;listeners&#x4E2D;&#x5305;&#x542B;&#x7684;listener&#x662F;&#x5426;&#x90FD;&#x5DF2;&#x7ECF;&#x542F;&#x52A8;&#x4E86;
listeners&#xFF1A;&#x5DF2;&#x6DFB;&#x52A0;&#x7684;listener&#x5217;&#x8868;&#xFF0C;&#x7528;&#x6765;&#x5904;&#x7406;watch&#x5230;&#x7684;&#x6570;&#x636E;
syncingListeners&#xFF1A;&#x5DF2;&#x6DFB;&#x52A0;&#x7684;listener&#x5217;&#x8868;&#xFF0C;&#x7528;&#x6765;&#x5904;&#x7406;list&#x6216;&#x8005;resync&#x7684;&#x6570;&#x636E;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">type</span> sharedProcessor <span class="token keyword">struct</span> <span class="token punctuation">{</span>
listenersStarted <span class="token builtin">bool</span>
listenersLock sync<span class="token punctuation">.</span>RWMutex
listeners <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>processorListener
syncingListeners <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>processorListener
clock clock<span class="token punctuation">.</span>Clock
wg wait<span class="token punctuation">.</span>Group
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x7406;&#x89E3;listeners&#x548C;syncinglisteners&#x7684;&#x533A;&#x522B;">&#x7406;&#x89E3;listeners&#x548C;syncingListeners&#x7684;&#x533A;&#x522B;</h4>
<p>processor&#x53EF;&#x4EE5;&#x652F;&#x6301;listener&#x7684;&#x7EF4;&#x5EA6;&#x914D;&#x7F6E;&#x662F;&#x5426;&#x9700;&#x8981;resync&#xFF1A;&#x4E00;&#x4E2A;informer&#x53EF;&#x4EE5;&#x914D;&#x7F6E;&#x591A;&#x4E2A;EventHandler&#xFF0C;&#x800C;&#x4E00;&#x4E2A;EventHandler&#x5BF9;&#x5E94;processor&#x4E2D;&#x7684;&#x4E00;&#x4E2A;listener&#xFF0C;&#x6BCF;&#x4E2A;listener&#x53EF;&#x4EE5;&#x914D;&#x7F6E;&#x9700;&#x4E0D;&#x9700;&#x8981;resync&#xFF0C;&#x5982;&#x679C;&#x67D0;&#x4E2A;listener&#x9700;&#x8981;resync&#xFF0C;&#x90A3;&#x4E48;&#x6DFB;&#x52A0;&#x5230;deltaFIFO&#x7684;Sync&#x589E;&#x91CF;&#x6700;&#x7EC8;&#x4E5F;&#x53EA;&#x4F1A;&#x56DE;&#x5230;&#x5BF9;&#x5E94;&#x7684;listener</p>
<p>reflector&#x4E2D;&#x4F1A;&#x5B9A;&#x65F6;&#x5224;&#x65AD;&#x6BCF;&#x4E00;&#x4E2A;listener&#x662F;&#x5426;&#x9700;&#x8981;&#x8FDB;&#x884C;resync&#xFF0C;&#x5224;&#x65AD;&#x7684;&#x4F9D;&#x636E;&#x662F;&#x770B;&#x914D;&#x7F6E;EventHandler&#x7684;&#x65F6;&#x5019;&#x6307;&#x5B9A;&#x7684;resyncPeriod&#xFF0C;0&#x4EE3;&#x8868;&#x8BE5;listener&#x4E0D;&#x9700;&#x8981;resync&#xFF0C;&#x5426;&#x5219;&#x5C31;&#x6BCF;&#x9694;resyncPeriod&#x770B;&#x770B;&#x662F;&#x5426;&#x5230;&#x65F6;&#x95F4;&#x4E86;</p>
<ul>
<li><p>listeners&#xFF1A;&#x8BB0;&#x5F55;&#x4E86;informer&#x6DFB;&#x52A0;&#x7684;&#x6240;&#x6709;listener</p>
</li>
<li><p>syncingListeners&#xFF1A;&#x8BB0;&#x5F55;&#x4E86;informer&#x4E2D;&#x54EA;&#x4E9B;listener&#x5904;&#x4E8E;sync&#x72B6;&#x6001;</p>
</li>
</ul>
<p>syncingListeners&#x662F;listeners&#x7684;&#x5B50;&#x96C6;&#xFF0C;syncingListeners&#x8BB0;&#x5F55;&#x90A3;&#x4E9B;&#x5F00;&#x542F;&#x4E86;resync&#x4E14;&#x65F6;&#x95F4;&#x5DF2;&#x7ECF;&#x5230;&#x8FBE;&#x4E86;&#x7684;listener&#xFF0C;&#x628A;&#x5B83;&#x4EEC;&#x653E;&#x5728;&#x4E00;&#x4E2A;&#x72EC;&#x7ACB;&#x7684;slice&#x662F;&#x907F;&#x514D;&#x4E0B;&#x9762;&#x5206;&#x6790;&#x7684;distribute&#x65B9;&#x6CD5;&#x4E2D;&#x628A;obj&#x589E;&#x52A0;&#x5230;&#x4E86;&#x8FD8;&#x4E0D;&#x9700;&#x8981;resync&#x7684;listener&#x4E2D;</p>
<h4 id="&#x4E3A;sharedprocessor&#x6DFB;&#x52A0;listener">&#x4E3A;sharedProcessor&#x6DFB;&#x52A0;listener</h4>
<p>&#x5728;sharedProcessor&#x4E2D;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;listener</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>sharedProcessor<span class="token punctuation">)</span> <span class="token function">addListenerLocked</span><span class="token punctuation">(</span>listener <span class="token operator">*</span>processorListener<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x540C;&#x65F6;&#x6DFB;&#x52A0;&#x5230;listeners&#x548C;syncingListeners&#x5217;&#x8868;&#xFF0C;&#x4F46;&#x5176;&#x5B9E;&#x6DFB;&#x52A0;&#x7684;&#x662F;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;&#x5F15;&#x7528;</span>
<span class="token comment">// &#x6240;&#x4EE5;&#x4E0B;&#x9762;run&#x542F;&#x52A8;&#x7684;&#x65F6;&#x5019;&#x53EA;&#x9700;&#x8981;&#x542F;&#x52A8;listeners&#x4E2D;listener&#x5C31;&#x53EF;&#x4EE5;&#x4E86;</span>
p<span class="token punctuation">.</span>listeners <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>listeners<span class="token punctuation">,</span> listener<span class="token punctuation">)</span>
p<span class="token punctuation">.</span>syncingListeners <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>syncingListeners<span class="token punctuation">,</span> listener<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x542F;&#x52A8;sharedprocessor&#x4E2D;&#x7684;listener">&#x542F;&#x52A8;sharedProcessor&#x4E2D;&#x7684;listener</h4>
<p>sharedProcessor&#x542F;&#x52A8;&#x6240;&#x6709;&#x7684;listener
&#x662F;&#x901A;&#x8FC7;&#x8C03;&#x7528;listener.run&#x548C;listener.pop&#x6765;&#x542F;&#x52A8;&#x4E00;&#x4E2A;listener&#xFF0C;&#x4E24;&#x4E2A;&#x65B9;&#x6CD5;&#x5177;&#x4F53;&#x4F5C;&#x7528;&#x770B;&#x4E0B;&#x6587;processorListener&#x8BF4;&#x660E;</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>sharedProcessor<span class="token punctuation">)</span> <span class="token function">run</span><span class="token punctuation">(</span>stopCh <span class="token operator">&lt;-</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">RLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">RUnlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> listener <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>listeners <span class="token punctuation">{</span>
<span class="token comment">// listener&#x7684;run&#x65B9;&#x6CD5;&#x4E0D;&#x65AD;&#x7684;&#x4ECE;listener&#x81EA;&#x8EAB;&#x7684;&#x7F13;&#x51B2;&#x533A;&#x53D6;&#x51FA;&#x5BF9;&#x8C61;&#x56DE;&#x8C03;handler</span>
p<span class="token punctuation">.</span>wg<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span>listener<span class="token punctuation">.</span>run<span class="token punctuation">)</span>
<span class="token comment">// listener&#x7684;pod&#x65B9;&#x6CD5;&#x4E0D;&#x65AD;&#x7684;&#x63A5;&#x6536;&#x5BF9;&#x8C61;&#x5E76;&#x6682;&#x5B58;&#x5728;&#x81EA;&#x8EAB;&#x7684;&#x7F13;&#x51B2;&#x533A;&#x4E2D;</span>
p<span class="token punctuation">.</span>wg<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span>listener<span class="token punctuation">.</span>pop<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
p<span class="token punctuation">.</span>listenersStarted <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token operator">&lt;-</span>stopCh
p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">RLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">RUnlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> listener <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>listeners <span class="token punctuation">{</span>
<span class="token function">close</span><span class="token punctuation">(</span>listener<span class="token punctuation">.</span>addCh<span class="token punctuation">)</span> <span class="token comment">// Tell .pop() to stop. .pop() will tell .run() to stop</span>
<span class="token punctuation">}</span>
p<span class="token punctuation">.</span>wg<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// Wait for all .pop() and .run() to stop</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="sharedprocessor&#x5206;&#x53D1;&#x5BF9;&#x8C61;">sharedProcessor&#x5206;&#x53D1;&#x5BF9;&#x8C61;</h4>
<p>distribute&#x65B9;&#x6CD5;&#x662F;&#x5728;&#x524D;&#x9762;&#x4ECB;&#x7ECD;<code>[deltaFIFO pop&#x51FA;&#x6765;&#x7684;&#x5BF9;&#x8C61;&#x5904;&#x7406;&#x903B;&#x8F91;]</code>&#x65F6;&#x63D0;&#x5230;&#x7684;&#xFF0C;&#x628A;notification&#x4E8B;&#x4EF6;&#x6DFB;&#x52A0;&#x5230;listener&#x4E2D;&#xFF0C;listener&#x5982;&#x4F55;pop&#x51FA;notification&#x56DE;&#x8C03;EventHandler&#x89C1;&#x4E0B;&#x6587;listener&#x90E8;&#x5206;&#x5206;&#x6790;</p>
<p>&#x5F53;&#x901A;&#x8FC7;distribute&#x5206;&#x53D1;&#x4ECE;deltaFIFO&#x83B7;&#x53D6;&#x7684;&#x5BF9;&#x8C61;&#x65F6;&#xFF0C;&#x5982;&#x679C;delta type&#x662F;Sync&#xFF0C;&#x90A3;&#x4E48;&#x5C31;&#x4F1A;&#x628A;&#x5BF9;&#x8C61;&#x4EA4;&#x7ED9;sync listener&#x6765;&#x5904;&#x7406;&#xFF0C;&#x800C;Sync&#x7C7B;&#x578B;&#x7684;delta&#x53EA;&#x80FD;&#x6765;&#x6E90;&#x4E8E;&#x4E0B;&#x9762;&#x4E24;&#x79CD;&#x60C5;&#x51B5;&#xFF1A;</p>
<ul>
<li>reflector list Replace&#x5230;deltaFIFO&#x7684;&#x5BF9;&#x8C61;&#xFF1A;&#x56E0;&#x4E3A;&#x9996;&#x6B21;&#x5728;sharedProcessor&#x589E;&#x52A0;&#x4E00;&#x4E2A;listener&#x7684;&#x65F6;&#x5019;&#x662F;&#x540C;&#x65F6;&#x52A0;&#x5728;listeners&#x548C;syncingListeners&#x4E2D;&#x7684;</li>
<li>reflector&#x5B9A;&#x65F6;&#x89E6;&#x53D1;resync local store&#x5230;deltaFIFO&#x7684;&#x5BF9;&#x8C61;&#xFF1A;&#x56E0;&#x4E3A;&#x6BCF;&#x6B21;reflector&#x8C03;&#x7528;processor&#x7684;shouldResync&#x65F6;&#xFF0C;&#x90FD;&#x4F1A;&#x628A;&#x8FBE;&#x5230;resync&#x6761;&#x4EF6;&#x7684;listener&#x7B5B;&#x9009;&#x51FA;&#x6765;&#x91CD;&#x65B0;&#x653E;&#x5230;p.syncingListeners</li>
</ul>
<p>&#x4E0A;&#x9762;&#x4E24;&#x79CD;&#x60C5;&#x51B5;&#x90FD;&#x53EF;&#x4EE5;&#x5728;p.syncingListeners&#x4E2D;&#x51C6;&#x5907;&#x597D;listener</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>sharedProcessor<span class="token punctuation">)</span> <span class="token function">distribute</span><span class="token punctuation">(</span>obj <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> sync <span class="token builtin">bool</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">RLock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">RUnlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// &#x5982;&#x679C;&#x662F;&#x901A;&#x8FC7;reflector list Replace&#x5230;deltaFIFO&#x7684;&#x5BF9;&#x8C61;&#x6216;&#x8005;reflector&#x5B9A;&#x65F6;&#x89E6;&#x53D1;resync&#x5230;deltaFIFO&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x90A3;&#x4E48;distribute&#x5230;syncingListeners</span>
<span class="token keyword">if</span> sync <span class="token punctuation">{</span>
<span class="token comment">// &#x4FDD;&#x8BC1;deltaFIFO Resync&#x65B9;&#x6CD5;&#x8FC7;&#x6765;&#x7684;delta obj&#x53EA;&#x7ED9;&#x5F00;&#x542F;&#x4E86;resync&#x80FD;&#x529B;&#x7684;listener</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> listener <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>syncingListeners <span class="token punctuation">{</span>
listener<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> listener <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>listeners <span class="token punctuation">{</span>
listener<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<h3 id="processorlistener&#x7ED3;&#x6784;">processorListener&#x7ED3;&#x6784;</h3>
<p>sharedProcessor&#x4E2D;&#x7684;listener&#x5177;&#x4F53;&#x7684;&#x7C7B;&#x578B;&#xFF1A;&#x8FD0;&#x8F6C;&#x903B;&#x8F91;&#x5C31;&#x662F;&#x628A;&#x7528;&#x6237;&#x901A;&#x8FC7;addCh&#x589E;&#x52A0;&#x7684;&#x4E8B;&#x4EF6;&#x53D1;&#x9001;&#x5230;nextCh&#x4F9B;run&#x65B9;&#x6CD5;&#x53D6;&#x51FA;&#x56DE;&#x8C03;Eventhandler&#xFF0C;&#x56E0;&#x4E3A;addCh&#x548C;nectCh&#x90FD;&#x662F;&#x65E0;&#x7F13;&#x51B2;channel&#xFF0C;&#x6240;&#x4EE5;&#x4E2D;&#x95F4;&#x5F15;&#x5165;ringBuffer&#x505A;&#x7F13;&#x5B58;</p>
<p>processorListener&#x662F;sharedIndexInformer&#x8C03;&#x7528;AddEventHandler&#x65F6;&#x521B;&#x5EFA;&#x5E76;&#x6DFB;&#x52A0;&#x5230;sharedProcessor&#xFF0C;&#x5BF9;&#x4E8E;&#x4E00;&#x4E2A;Informer&#xFF0C;&#x53EF;&#x4EE5;&#x591A;&#x6B21;&#x8C03;&#x7528;AddEventHandler&#x6765;&#x6DFB;&#x52A0;&#x591A;&#x4E2A;listener</p>
<blockquote>
<p>addCh&#xFF1A;&#x65E0;&#x7F13;&#x51B2;&#x7684;chan&#xFF0C;listener&#x7684;pod&#x65B9;&#x6CD5;&#x4E0D;&#x65AD;&#x4ECE;addCh&#x53D6;&#x51FA;&#x5BF9;&#x8C61;&#x4E22;&#x7ED9;nextCh&#x3002;addCh&#x4E2D;&#x7684;&#x5BF9;&#x8C61;&#x6765;&#x6E90;&#x4E8E;listener&#x7684;add&#x65B9;&#x6CD5;&#xFF0C;&#x5982;&#x679C;nextCh&#x4E0D;&#x80FD;&#x53CA;&#x65F6;&#x6D88;&#x8D39;&#xFF0C;&#x5219;&#x653E;&#x5165;&#x7F13;&#x51B2;&#x533A;pendingNotifications
nextCh&#xFF1A;&#x65E0;&#x7F13;&#x51B2;&#x7684;chan&#xFF0C;listener&#x7684;run&#x65B9;&#x6CD5;&#x4E0D;&#x65AD;&#x4ECE;nextCh&#x53D6;&#x51FA;&#x5BF9;&#x8C61;&#x56DE;&#x8C03;&#x7528;&#x6237;handler&#x3002;nextCh&#x7684;&#x5BF9;&#x8C61;&#x6765;&#x6E90;&#x4E8E;addCh&#x6216;&#x8005;&#x7F13;&#x51B2;&#x533A;
pendingNotifications&#xFF1A;&#x4E00;&#x4E2A;&#x65E0;&#x5BB9;&#x91CF;&#x9650;&#x5236;&#x7684;&#x73AF;&#x5F62;&#x7F13;&#x51B2;&#x533A;&#xFF0C;&#x53EF;&#x4EE5;&#x7406;&#x89E3;&#x4E3A;&#x53EF;&#x4EE5;&#x65E0;&#x9650;&#x5B58;&#x50A8;&#x7684;&#x961F;&#x5217;&#xFF0C;&#x7528;&#x6765;&#x5B58;&#x50A8;deltaFIFO&#x5206;&#x53D1;&#x8FC7;&#x6765;&#x7684;&#x6D88;&#x606F;
nextResync&#xFF1A;&#x7531;resyncPeriod&#x548C;requestedResyncPeriod&#x8BA1;&#x7B97;&#x5F97;&#x51FA;&#xFF0C;&#x4E0E;&#x5F53;&#x524D;&#x65F6;&#x95F4;now&#x6BD4;&#x8F83;&#x5224;&#x65AD;listener&#x662F;&#x5426;&#x8BE5;&#x8FDB;&#x884C;resync&#x4E86;
resyncPeriod&#xFF1A;listener&#x81EA;&#x8EAB;&#x671F;&#x5F85;&#x591A;&#x957F;&#x65F6;&#x95F4;&#x8FDB;&#x884C;resync
requestedResyncPeriod&#xFF1A;informer&#x5E0C;&#x671B;listener&#x591A;&#x957F;&#x65F6;&#x95F4;&#x8FDB;&#x884C;resync</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">type</span> processorListener <span class="token keyword">struct</span> <span class="token punctuation">{</span>
nextCh <span class="token keyword">chan</span> <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
addCh <span class="token keyword">chan</span> <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
handler ResourceEventHandler
<span class="token comment">// pendingNotifications is an unbounded ring buffer that holds all notifications not yet distributed.</span>
<span class="token comment">// There is one per listener, but a failing/stalled listener will have infinite pendingNotifications</span>
<span class="token comment">// added until we OOM.</span>
<span class="token comment">// TODO: This is no worse than before, since reflectors were backed by unbounded DeltaFIFOs, but</span>
<span class="token comment">// we should try to do something better.</span>
pendingNotifications buffer<span class="token punctuation">.</span>RingGrowing
<span class="token comment">// requestedResyncPeriod is how frequently the listener wants a full resync from the shared informer</span>
requestedResyncPeriod time<span class="token punctuation">.</span>Duration
<span class="token comment">// resyncPeriod is how frequently the listener wants a full resync from the shared informer. This</span>
<span class="token comment">// value may differ from requestedResyncPeriod if the shared informer adjusts it to align with the</span>
<span class="token comment">// informer&apos;s overall resync check period.</span>
resyncPeriod time<span class="token punctuation">.</span>Duration
<span class="token comment">// nextResync is the earliest time the listener should get a full resync</span>
nextResync time<span class="token punctuation">.</span>Time
<span class="token comment">// resyncLock guards access to resyncPeriod and nextResync</span>
resyncLock sync<span class="token punctuation">.</span>Mutex
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x5728;listener&#x4E2D;&#x6DFB;&#x52A0;&#x4E8B;&#x4EF6;">&#x5728;listener&#x4E2D;&#x6DFB;&#x52A0;&#x4E8B;&#x4EF6;</h4>
<p>shareProcessor&#x4E2D;&#x7684;distribute&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x7684;&#x662F;listener&#x7684;add&#x6765;&#x5411;addCh&#x589E;&#x52A0;&#x6D88;&#x606F;&#xFF0C;&#x6CE8;&#x610F;addCh&#x662F;&#x65E0;&#x7F13;&#x51B2;&#x7684;chan&#xFF0C;&#x4F9D;&#x8D56;pop&#x4E0D;&#x65AD;&#x4ECE;addCh&#x53D6;&#x51FA;&#x6570;&#x636E;</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>processorListener<span class="token punctuation">)</span> <span class="token function">add</span><span class="token punctuation">(</span>notification <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x867D;&#x7136;p.addCh&#x662F;&#x4E00;&#x4E2A;&#x65E0;&#x7F13;&#x51B2;&#x7684;channel&#xFF0C;&#x4F46;&#x662F;&#x56E0;&#x4E3A;listener&#x4E2D;&#x5B58;&#x5728;ring buffer&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x91CC;&#x5E76;&#x4E0D;&#x4F1A;&#x4E00;&#x76F4;&#x963B;&#x585E;</span>
p<span class="token punctuation">.</span>addCh <span class="token operator">&lt;-</span> notification
<span class="token punctuation">}</span>
</code></pre>
<h4 id="&#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;resync">&#x5224;&#x65AD;&#x662F;&#x5426;&#x9700;&#x8981;resync</h4>
<p>&#x5982;&#x679C;resyncPeriod&#x4E3A;0&#x8868;&#x793A;&#x4E0D;&#x9700;&#x8981;resync&#xFF0C;&#x5426;&#x5219;&#x5224;&#x65AD;&#x5F53;&#x524D;&#x65F6;&#x95F4;now&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x8D85;&#x8FC7;&#x4E86;nextResync&#xFF0C;&#x662F;&#x7684;&#x8BDD;&#x5219;&#x8FD4;&#x56DE;true&#x8868;&#x793A;&#x9700;&#x8981;resync&#x3002;&#x5176;&#x4E2D;nextResync&#x5728;&#x6BCF;&#x6B21;&#x8C03;&#x7528;listener&#x7684;shouldResync&#x65B9;&#x6CD5;&#x6210;&#x529F;&#x65F6;&#x66F4;&#x65B0;</p>
<pre class="language-"><code class="lang-go"><span class="token comment">// shouldResync queries every listener to determine if any of them need a resync, based on each</span>
<span class="token comment">// listener&apos;s resyncPeriod.</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>sharedProcessor<span class="token punctuation">)</span> <span class="token function">shouldResync</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span>
p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">Lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> p<span class="token punctuation">.</span>listenersLock<span class="token punctuation">.</span><span class="token function">Unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token comment">// &#x8FD9;&#x91CC;&#x6BCF;&#x6B21;&#x90FD;&#x4F1A;&#x5148;&#x7F6E;&#x7A7A;&#x5217;&#x8868;&#xFF0C;&#x4FDD;&#x8BC1;&#x91CC;&#x9762;&#x8BB0;&#x5F55;&#x4E86;&#x5F53;&#x524D;&#x9700;&#x8981;resync&#x7684;listener</span>
p<span class="token punctuation">.</span>syncingListeners <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">*</span>processorListener<span class="token punctuation">{</span><span class="token punctuation">}</span>
resyncNeeded <span class="token operator">:=</span> <span class="token boolean">false</span>
now <span class="token operator">:=</span> p<span class="token punctuation">.</span>clock<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> listener <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>listeners <span class="token punctuation">{</span>
<span class="token comment">// need to loop through all the listeners to see if they need to resync so we can prepare any</span>
<span class="token comment">// listeners that are going to be resyncing.</span>
<span class="token keyword">if</span> listener<span class="token punctuation">.</span><span class="token function">shouldResync</span><span class="token punctuation">(</span>now<span class="token punctuation">)</span> <span class="token punctuation">{</span>
resyncNeeded <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token comment">// &#x8FBE;&#x5230;resync&#x6761;&#x4EF6;&#x7684;listener&#x88AB;&#x52A0;&#x5165;syncingListeners</span>
p<span class="token punctuation">.</span>syncingListeners <span class="token operator">=</span> <span class="token function">append</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>syncingListeners<span class="token punctuation">,</span> listener<span class="token punctuation">)</span>
listener<span class="token punctuation">.</span><span class="token function">determineNextResync</span><span class="token punctuation">(</span>now<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> resyncNeeded
<span class="token punctuation">}</span>
</code></pre>
<h4 id="listener&#x7684;run&#x65B9;&#x6CD5;&#x56DE;&#x8C03;eventhandler">listener&#x7684;run&#x65B9;&#x6CD5;&#x56DE;&#x8C03;EventHandler</h4>
<p>listener&#x7684;run&#x65B9;&#x6CD5;&#x4E0D;&#x65AD;&#x7684;&#x4ECE;nextCh&#x4E2D;&#x83B7;&#x53D6;notification&#xFF0C;&#x5E76;&#x6839;&#x636E;notification&#x7684;&#x7C7B;&#x578B;&#x6765;&#x8C03;&#x7528;&#x7528;&#x6237;&#x81EA;&#x5B9A;&#x7684;EventHandler</p>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>processorListener<span class="token punctuation">)</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// this call blocks until the channel is closed. When a panic happens during the notification</span>
<span class="token comment">// we will catch it, **the offending item will be skipped!**, and after a short delay (one second)</span>
<span class="token comment">// the next notification will be attempted. This is usually better than the alternative of never</span>
<span class="token comment">// delivering again.</span>
stopCh <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> <span class="token keyword">struct</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
wait<span class="token punctuation">.</span><span class="token function">Until</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// this gives us a few quick retries before a long pause and then a few more quick retries</span>
err <span class="token operator">:=</span> wait<span class="token punctuation">.</span><span class="token function">ExponentialBackoff</span><span class="token punctuation">(</span>retry<span class="token punctuation">.</span>DefaultRetry<span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token builtin">bool</span><span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">for</span> next <span class="token operator">:=</span> <span class="token keyword">range</span> p<span class="token punctuation">.</span>nextCh <span class="token punctuation">{</span>
<span class="token keyword">switch</span> notification <span class="token operator">:=</span> next<span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token keyword">type</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">case</span> updateNotification<span class="token punctuation">:</span>
<span class="token comment">// &#x56DE;&#x8C03;&#x7528;&#x6237;&#x914D;&#x7F6E;&#x7684;handler</span>
p<span class="token punctuation">.</span>handler<span class="token punctuation">.</span><span class="token function">OnUpdate</span><span class="token punctuation">(</span>notification<span class="token punctuation">.</span>oldObj<span class="token punctuation">,</span> notification<span class="token punctuation">.</span>newObj<span class="token punctuation">)</span>
<span class="token keyword">case</span> addNotification<span class="token punctuation">:</span>
p<span class="token punctuation">.</span>handler<span class="token punctuation">.</span><span class="token function">OnAdd</span><span class="token punctuation">(</span>notification<span class="token punctuation">.</span>newObj<span class="token punctuation">)</span>
<span class="token keyword">case</span> deleteNotification<span class="token punctuation">:</span>
p<span class="token punctuation">.</span>handler<span class="token punctuation">.</span><span class="token function">OnDelete</span><span class="token punctuation">(</span>notification<span class="token punctuation">.</span>oldObj<span class="token punctuation">)</span>
<span class="token keyword">default</span><span class="token punctuation">:</span>
utilruntime<span class="token punctuation">.</span><span class="token function">HandleError</span><span class="token punctuation">(</span>fmt<span class="token punctuation">.</span><span class="token function">Errorf</span><span class="token punctuation">(</span><span class="token string">&quot;unrecognized notification: %T&quot;</span><span class="token punctuation">,</span> next<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// the only way to get here is if the p.nextCh is empty and closed</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// the only way to get here is if the p.nextCh is empty and closed</span>
<span class="token keyword">if</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
<span class="token function">close</span><span class="token punctuation">(</span>stopCh<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token operator">*</span>time<span class="token punctuation">.</span>Minute<span class="token punctuation">,</span> stopCh<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="addch&#x5230;nextch&#x7684;&#x5BF9;&#x8C61;&#x4F20;&#x9012;">addCh&#x5230;nextCh&#x7684;&#x5BF9;&#x8C61;&#x4F20;&#x9012;</h4>
<p>listener&#x4E2D;pop&#x65B9;&#x6CD5;&#x7684;&#x903B;&#x8F91;&#x76F8;&#x5BF9;&#x6BD4;&#x8F83;&#x7ED5;&#xFF0C;&#x6700;&#x7EC8;&#x76EE;&#x7684;&#x5C31;&#x662F;&#x628A;&#x5206;&#x53D1;&#x5230;addCh&#x7684;&#x6570;&#x636E;&#x4ECE;nextCh&#x6216;&#x8005;pendingNotifications&#x53D6;&#x51FA;&#x6765;</p>
<blockquote>
<p>notification&#x53D8;&#x91CF;&#x8BB0;&#x5F55;&#x4E0B;&#x4E00;&#x6B21;&#x8981;&#x88AB;&#x653E;&#x5230;p.nextCh&#x4F9B;pop&#x65B9;&#x6CD5;&#x53D6;&#x51FA;&#x7684;&#x5BF9;&#x8C61;
&#x5F00;&#x59CB;seletct&#x65F6;&#x5FC5;&#x7136;&#x53EA;&#x6709;case2&#x53EF;&#x80FD;ready
Case2&#x505A;&#x7684;&#x4E8B;&#x53EF;&#x4EE5;&#x63CF;&#x8FF0;&#x4E3A;&#xFF1A;&#x4ECE;p.addCh&#x83B7;&#x53D6;&#x5BF9;&#x8C61;&#xFF0C;&#x5982;&#x679C;&#x4E34;&#x65F6;&#x53D8;&#x91CF;notification&#x8FD8;&#x662F;nil&#xFF0C;&#x8BF4;&#x660E;&#x9700;&#x8981;&#x5F80;notification&#x8D4B;&#x503C;&#xFF0C;&#x4F9B;case1&#x63A8;&#x9001;&#x5230;p.nextCh
&#x5982;&#x679C;notification&#x5DF2;&#x7ECF;&#x6709;&#x503C;&#x4E86;&#xFF0C;&#x90A3;&#x4E2A;&#x5F53;&#x524D;&#x4ECE;p.addCh&#x53D6;&#x51FA;&#x7684;&#x503C;&#x8981;&#x5148;&#x653E;&#x5230;&#x73AF;&#x5F62;&#x7F13;&#x51B2;&#x533A;&#x4E2D;</p>
<p>Case1&#x505A;&#x7684;&#x4E8B;&#x53EF;&#x4EE5;&#x63CF;&#x8FF0;&#x4E3A;&#xFF1A;&#x770B;&#x770B;&#x80FD;&#x4E0D;&#x80FD;&#x628A;&#x4E34;&#x65F6;&#x53D8;&#x91CF;notification&#x63A8;&#x9001;&#x5230;nextCh&#xFF08;nil chan&#x4F1A;&#x963B;&#x585E;&#x5728;&#x8BFB;&#x5199;&#x64CD;&#x4F5C;&#x4E0A;&#xFF09;&#xFF0C;&#x53EF;&#x4EE5;&#x5199;&#x7684;&#x8BDD;&#xFF0C;&#x8BF4;&#x660E;&#x8FD9;&#x4E2A;nextCh&#x662F;p.nextCh&#xFF0C;&#x5199;&#x6210;&#x529F;&#x4E4B;&#x540E;&#xFF0C;&#x9700;&#x8981;&#x4ECE;&#x7F13;&#x5B58;&#x4E2D;&#x53D6;&#x51FA;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#x653E;&#x5230;notification&#x4E3A;&#x4E0B;&#x6B21;&#x6267;&#x884C;&#x8FD9;&#x4E2A;case&#x505A;&#x51C6;&#x5907;&#xFF0C;&#x5982;&#x679C;&#x7F13;&#x5B58;&#x662F;&#x7A7A;&#x7684;&#xFF0C;&#x901A;&#x8FC7;&#x628A;nextCh chan&#x8BBE;&#x7F6E;&#x4E3A;nil&#x6765;&#x7981;&#x7528;case1&#xFF0C;&#x4EE5;&#x4FBF;case2&#x4F4D;notification&#x8D4B;&#x503C;</p>
</blockquote>
<pre class="language-"><code class="lang-go"><span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>processorListener<span class="token punctuation">)</span> <span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">defer</span> utilruntime<span class="token punctuation">.</span><span class="token function">HandleCrash</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">defer</span> <span class="token function">close</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>nextCh<span class="token punctuation">)</span> <span class="token comment">// Tell .run() to stop</span>
<span class="token comment">//nextCh&#x6CA1;&#x6709;&#x5229;&#x7528;make&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x5C06;&#x963B;&#x585E;&#x5728;&#x8BFB;&#x548C;&#x5199;&#x4E0A;</span>
<span class="token keyword">var</span> nextCh <span class="token keyword">chan</span><span class="token operator">&lt;-</span> <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token comment">//notification&#x521D;&#x59CB;&#x503C;&#x4E3A;nil</span>
<span class="token keyword">var</span> notification <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">for</span> <span class="token punctuation">{</span>
<span class="token keyword">select</span> <span class="token punctuation">{</span>
<span class="token comment">// &#x6267;&#x884C;&#x8FD9;&#x4E2A;case&#xFF0C;&#x76F8;&#x5F53;&#x4E8E;&#x7ED9;p.nextCh&#x6DFB;&#x52A0;&#x6765;&#x81EA;p.addCh&#x7684;&#x5185;&#x5BB9;</span>
<span class="token keyword">case</span> nextCh <span class="token operator">&lt;-</span> notification<span class="token punctuation">:</span>
<span class="token comment">// Notification dispatched</span>
<span class="token keyword">var</span> ok <span class="token builtin">bool</span>
<span class="token comment">//&#x524D;&#x9762;&#x7684;notification&#x5DF2;&#x7ECF;&#x52A0;&#x5230;p.nextCh&#x4E86;&#xFF0C; &#x4E3A;&#x4E0B;&#x4E00;&#x6B21;&#x8FD9;&#x4E2A;case&#x518D;&#x6B21;ready&#x505A;&#x51C6;&#x5907;</span>
notification<span class="token punctuation">,</span> ok <span class="token operator">=</span> p<span class="token punctuation">.</span>pendingNotifications<span class="token punctuation">.</span><span class="token function">ReadOne</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">{</span> <span class="token comment">// Nothing to pop</span>
nextCh <span class="token operator">=</span> <span class="token boolean">nil</span> <span class="token comment">// Disable this select case</span>
<span class="token punctuation">}</span>
<span class="token comment">//&#x7B2C;&#x4E00;&#x6B21;select&#x53EA;&#x6709;&#x8FD9;&#x4E2A;case ready</span>
<span class="token keyword">case</span> notificationToAdd<span class="token punctuation">,</span> ok <span class="token operator">:=</span> <span class="token operator">&lt;-</span>p<span class="token punctuation">.</span>addCh<span class="token punctuation">:</span>
<span class="token keyword">if</span> <span class="token operator">!</span>ok <span class="token punctuation">{</span>
<span class="token keyword">return</span>
<span class="token punctuation">}</span>
<span class="token keyword">if</span> notification <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token comment">// No notification to pop (and pendingNotifications is empty)</span>
<span class="token comment">// Optimize the case - skip adding to pendingNotifications</span>
<span class="token comment">//&#x4E3A;notification&#x8D4B;&#x503C;</span>
notification <span class="token operator">=</span> notificationToAdd
<span class="token comment">//&#x5524;&#x9192;&#x7B2C;&#x4E00;&#x4E2A;case</span>
nextCh <span class="token operator">=</span> p<span class="token punctuation">.</span>nextCh
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// There is already a notification waiting to be dispatched</span>
<span class="token comment">//select&#x6CA1;&#x6709;&#x547D;&#x4E2D;&#x7B2C;&#x4E00;&#x4E2A;case&#xFF0C;&#x90A3;&#x4E48;notification&#x5C31;&#x6CA1;&#x6709;&#x88AB;&#x6D88;&#x8017;&#xFF0C;&#x90A3;&#x4E48;&#x628A;&#x4ECE;p.addCh&#x83B7;&#x53D6;&#x7684;&#x5BF9;&#x8C61;&#x52A0;&#x5230;&#x7F13;&#x5B58;&#x4E2D;</span>
p<span class="token punctuation">.</span>pendingNotifications<span class="token punctuation">.</span><span class="token function">WriteOne</span><span class="token punctuation">(</span>notificationToAdd<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<footer class="page-footer"><span class="copyright"><a href="https://mp.weixin.qq.com/s/vWlSdzz2MNdXRr0sd2-LFg" target="_blank">&#x52A0;&#x5165;&#x4E91;&#x539F;&#x751F;&#x793E;&#x533A;</a><p></p>Copyright &#xA9; 2017-2021 | Distributed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank">CC BY 4.0</a> | <a href="https://jimmysong.io" target="_blank">jimmysong.io</a> all right reserved&#xFF0C;powered by Gitbook</span><span class="footer-modification"> Updated at
2021-12-17 03:57:47
</span></footer>
</section>
</div>
<div class="search-results">
<div class="has-results">
<h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
<ul class="search-results-list"></ul>
</div>
<div class="no-results">
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
</div>
</div>
</div>
</div>
</div>
</div>
<a href="client-go-sample.html" class="navigation navigation-prev " aria-label="Previous page: client-go 示例">
<i class="fa fa-angle-left"></i>
</a>
<a href="operator.html" class="navigation navigation-next " aria-label="Next page: Operator">
<i class="fa fa-angle-right"></i>
</a>
</div>
<script>
var gitbook = gitbook || [];
gitbook.push(function() {
gitbook.page.hasChanged({"page":{"title":"client-go 中的 informer 源码分析","level":"9.5.1","depth":2,"next":{"title":"Operator","level":"9.6","depth":1,"path":"develop/operator.md","ref":"develop/operator.md","articles":[{"title":"operator-sdk","level":"9.6.1","depth":2,"path":"develop/operator-sdk.md","ref":"develop/operator-sdk.md","articles":[]}]},"previous":{"title":"client-go 示例","level":"9.5","depth":1,"path":"develop/client-go-sample.md","ref":"develop/client-go-sample.md","articles":[{"title":"client-go 中的 informer 源码分析","level":"9.5.1","depth":2,"path":"develop/client-go-informer-sourcecode-analyse.md","ref":"develop/client-go-informer-sourcecode-analyse.md","articles":[]}]},"dir":"ltr"},"config":{"plugins":["github","codesnippet","splitter","page-toc-button","image-captions","editlink","back-to-top-button","-lunr","-search","search-plus","github-buttons@2.1.0","favicon@^0.0.2","tbfed-pagefooter@^0.0.1","3-ba","theme-default","-highlight","prism","prism-themes","lightbox","ga","sitemap-general"],"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"},"pluginsConfig":{"tbfed-pagefooter":{"copyright":"<a href=https://mp.weixin.qq.com/s/vWlSdzz2MNdXRr0sd2-LFg>加入云原生社区</a></p>Copyright © 2017-2021 | Distributed under <a href=https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh>CC BY 4.0</a> | <a href=https://jimmysong.io>jimmysong.io</a>","modify_label":" Updated at ","modify_format":"YYYY-MM-DD HH:mm:ss"},"prism":{"css":["prism-themes/themes/prism-ghcolors.css"]},"github":{"url":"https://github.com/rootsongjc/kubernetes-handbook"},"editlink":{"label":"编辑本页","multilingual":false,"base":"https://github.com/rootsongjc/kubernetes-handbook/blob/master/"},"splitter":{},"codesnippet":{},"sitemap-general":{"prefix":"https://jimmysong.io/kubernetes-handbook/"},"fontsettings":{"theme":"white","family":"sans","size":2},"favicon":{"shortcut":"favicon.ico","bookmark":"favicon.ico"},"lightbox":{"jquery":true,"sameUuid":false},"page-toc-button":{},"back-to-top-button":{},"prism-themes":{},"github-buttons":{"repo":"rootsongjc/kubernetes-handbook","types":["star"],"size":"small"},"3-ba":{"configuration":"auto","token":"11f7d254cfa4e0ca44b175c66d379ecc"},"ga":{"configuration":"auto","token":"UA-93485976-1"},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"theme-default":{"showLevel":true,"styles":{"ebook":"styles/ebook.css","epub":"styles/epub.css","mobi":"styles/mobi.css","pdf":"styles/pdf.css","print":"styles/print.css","website":"styles/website.css"}},"search-plus":{},"image-captions":{"caption":"图 _PAGE_LEVEL_._PAGE_IMAGE_NUMBER__CAPTION_","variable_name":"_pictures"}},"theme":"default","author":"Jimmy Song宋净超","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{"_pictures":[{"backlink":"cloud-native/kubernetes-and-cloud-native-app-overview.html#fig2.4.1","level":"2.4","list_caption":"Figure: 云计算演进历程","alt":"云计算演进历程","nro":1,"url":"../images/cloud-computing-evolution-road.jpg","index":1,"caption_template":"图 _PAGE_LEVEL_._PAGE_IMAGE_NUMBER__CAPTION_","label":"云计算演进历程","attributes":{},"skip":false,"key":"2.4.1"},{"backlink":"cloud-native/kubernetes-and-cloud-native-app-overview.html#fig2.4.2","level":"2.4","list_caption":"Figure: 来自Twitter @MarcWilczek","alt":"来自Twitter @MarcWilczek","nro":2,"url":"../images/cloud-native-comes-of-age.jpg","index":2,"caption_template":"图 _PAGE_LEVEL_._PAGE_IMAGE_NUMBER__CAPTION_","label":"来自Twitter @MarcWilczek","attributes":{},"skip":false,"key":"2.4.2"},{"backlink":"cloud-native/kubernetes-and
});
</script>
</div>
<script src="../gitbook/gitbook.js"></script>
<script src="../gitbook/theme.js"></script>
<script src="../gitbook/gitbook-plugin-github/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-splitter/splitter.js"></script>
<script src="../gitbook/gitbook-plugin-page-toc-button/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-editlink/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-back-to-top-button/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-search-plus/jquery.mark.min.js"></script>
<script src="../gitbook/gitbook-plugin-search-plus/search.js"></script>
<script src="../gitbook/gitbook-plugin-github-buttons/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-3-ba/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-lightbox/js/lightbox.min.js"></script>
<script src="../gitbook/gitbook-plugin-ga/plugin.js"></script>
<script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
<script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
</body>
</html>