tools/cache 深度分析(下篇)--- RealFIFO 深度、集成架构、生命周期、设计模式总结
基于
client-go v0.36.1tools/cache/源码
五、RealFIFO 深度解析
5.1 RealFIFO vs DeltaFIFO --- 完整对比
| 维度 | DeltaFIFO | RealFIFO |
|---|---|---|
| 内部结构 | items map[string]Deltas + queue []string |
items []Delta (纯列表) |
| 去重 | 同 key 的 Delta 合并到 Deltas | 不去重,每个 Delta 独立 |
| Pop 粒度 | Pop() 返回一个 key 的所有 Deltas | Pop() 返回单个 Delta 包装为 Deltas |
| 批量处理 | 无 | PopBatch() 最多 batchSize 个 Delta |
| 原子 Replace | 无,逐个 Replaced/Added | ReplacedAll 原子事件 |
| 原子 Resync | 无,逐个 Sync | SyncAll 原子事件 |
| Bookmark Delta | 无 | 支持,用于 RV 进度跟踪 |
| KnownObjects | 必须提供 | AtomicEvents=true 时不提供 |
| 处理时解锁 | 不支持 | UnlockWhileProcessing=true 时支持 |
| DeltaType | Sync/Added/Updated/Deleted/Replaced | +ReplacedAll/SyncAll/Bookmark |
| 同步检测 | HasSynced() 基于 initialPopulationCount | HasSynced() + Done() channel |
| 适用场景 | 传统 SharedInformer | 高性能 Informer (KCM) |
5.2 RealFIFO Replace 的 reconcileReplacement
非原子模式下,Replace 需要合成 Deleted Delta:
#mermaid-svg-hEj1ICQgwFeWhCiC{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hEj1ICQgwFeWhCiC .error-icon{fill:#552222;}#mermaid-svg-hEj1ICQgwFeWhCiC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hEj1ICQgwFeWhCiC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hEj1ICQgwFeWhCiC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hEj1ICQgwFeWhCiC .marker.cross{stroke:#333333;}#mermaid-svg-hEj1ICQgwFeWhCiC svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hEj1ICQgwFeWhCiC p{margin:0;}#mermaid-svg-hEj1ICQgwFeWhCiC .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hEj1ICQgwFeWhCiC .cluster-label text{fill:#333;}#mermaid-svg-hEj1ICQgwFeWhCiC .cluster-label span{color:#333;}#mermaid-svg-hEj1ICQgwFeWhCiC .cluster-label span p{background-color:transparent;}#mermaid-svg-hEj1ICQgwFeWhCiC .label text,#mermaid-svg-hEj1ICQgwFeWhCiC span{fill:#333;color:#333;}#mermaid-svg-hEj1ICQgwFeWhCiC .node rect,#mermaid-svg-hEj1ICQgwFeWhCiC .node circle,#mermaid-svg-hEj1ICQgwFeWhCiC .node ellipse,#mermaid-svg-hEj1ICQgwFeWhCiC .node polygon,#mermaid-svg-hEj1ICQgwFeWhCiC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hEj1ICQgwFeWhCiC .rough-node .label text,#mermaid-svg-hEj1ICQgwFeWhCiC .node .label text,#mermaid-svg-hEj1ICQgwFeWhCiC .image-shape .label,#mermaid-svg-hEj1ICQgwFeWhCiC .icon-shape .label{text-anchor:middle;}#mermaid-svg-hEj1ICQgwFeWhCiC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hEj1ICQgwFeWhCiC .rough-node .label,#mermaid-svg-hEj1ICQgwFeWhCiC .node .label,#mermaid-svg-hEj1ICQgwFeWhCiC .image-shape .label,#mermaid-svg-hEj1ICQgwFeWhCiC .icon-shape .label{text-align:center;}#mermaid-svg-hEj1ICQgwFeWhCiC .node.clickable{cursor:pointer;}#mermaid-svg-hEj1ICQgwFeWhCiC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hEj1ICQgwFeWhCiC .arrowheadPath{fill:#333333;}#mermaid-svg-hEj1ICQgwFeWhCiC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hEj1ICQgwFeWhCiC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hEj1ICQgwFeWhCiC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hEj1ICQgwFeWhCiC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hEj1ICQgwFeWhCiC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hEj1ICQgwFeWhCiC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hEj1ICQgwFeWhCiC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hEj1ICQgwFeWhCiC .cluster text{fill:#333;}#mermaid-svg-hEj1ICQgwFeWhCiC .cluster span{color:#333;}#mermaid-svg-hEj1ICQgwFeWhCiC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hEj1ICQgwFeWhCiC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hEj1ICQgwFeWhCiC rect.text{fill:none;stroke-width:0;}#mermaid-svg-hEj1ICQgwFeWhCiC .icon-shape,#mermaid-svg-hEj1ICQgwFeWhCiC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hEj1ICQgwFeWhCiC .icon-shape p,#mermaid-svg-hEj1ICQgwFeWhCiC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hEj1ICQgwFeWhCiC .icon-shape .label rect,#mermaid-svg-hEj1ICQgwFeWhCiC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hEj1ICQgwFeWhCiC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hEj1ICQgwFeWhCiC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hEj1ICQgwFeWhCiC :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Yes
No
Yes
No
Yes
No
Yes
No
Replace(newItems, rv)
计算 newKeys set
提取 queuedKeys + lastQueuedItemForKey
遍历 queuedKeys:
key in newKeys?
lastDelta.Type == Deleted?
onDelete(DeletedFinalStateUnknown)
遍历 knownKeys:
key in newKeys?
key in queuedItems?
knownObjects.GetByKey(key)
onDelete(DeletedFinalStateUnknown)
遍历 newItems → onReplace(obj)
跳过 (仍在 newItems 中)
跳过 (已有 Delete)
跳过
已在 queue 中处理
三阶段合成逻辑
- Queue 内检测:已在队列中但不在 newItems 中的 key → 合成 Deleted(用队列中的最后状态)
- KnownObjects 检测:在 KnownObjects 中但不在 newItems 也不在队列中的 key → 合成 Deleted(用 Store 中的状态)
- 添加新项:所有 newItems 以 Replaced Delta 添加
5.3 RealFIFO Resync
原子模式
go
if f.emitAtomicEvents {
return f.addResyncToItemsLocked()
// 添加单个 SyncAll Delta
}
非原子模式
go
// 1. 收集队列中已有的 key
keysInQueue := sets.Set[string]{}
for _, item := range f.items {
key, _ := f.keyOf(item.Object)
keysInQueue.Insert(key)
}
// 2. 遍历 knownObjects 的所有 key
knownKeys := f.knownObjects.ListKeys()
for _, knownKey := range knownKeys {
if keysInQueue.Has(knownKey) {
continue // 已在队列中 → 跳过
}
knownObj, exists, _ := f.knownObjects.GetByKey(knownKey)
if !exists { continue }
f.addToItems_locked(Sync, true, knownObj)
// true = skipTransform (Sync 不需要再次转换)
}
5.4 RealFIFO PopBatch 的去重策略
PopBatch 从队列头部开始收集 Delta,直到遇到以下情况之一停止:
- 达到 batchSize(默认 1000)
- 超过 initialPopulationCount 范围
- 遇到非 batchable Delta(ReplacedAll/SyncAll/Bookmark)
- 遇到重复 key
- keyOf 返回错误
#mermaid-svg-SGVRsHoxYQaQA0pQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SGVRsHoxYQaQA0pQ .error-icon{fill:#552222;}#mermaid-svg-SGVRsHoxYQaQA0pQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SGVRsHoxYQaQA0pQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .marker.cross{stroke:#333333;}#mermaid-svg-SGVRsHoxYQaQA0pQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SGVRsHoxYQaQA0pQ p{margin:0;}#mermaid-svg-SGVRsHoxYQaQA0pQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .cluster-label text{fill:#333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .cluster-label span{color:#333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .cluster-label span p{background-color:transparent;}#mermaid-svg-SGVRsHoxYQaQA0pQ .label text,#mermaid-svg-SGVRsHoxYQaQA0pQ span{fill:#333;color:#333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .node rect,#mermaid-svg-SGVRsHoxYQaQA0pQ .node circle,#mermaid-svg-SGVRsHoxYQaQA0pQ .node ellipse,#mermaid-svg-SGVRsHoxYQaQA0pQ .node polygon,#mermaid-svg-SGVRsHoxYQaQA0pQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SGVRsHoxYQaQA0pQ .rough-node .label text,#mermaid-svg-SGVRsHoxYQaQA0pQ .node .label text,#mermaid-svg-SGVRsHoxYQaQA0pQ .image-shape .label,#mermaid-svg-SGVRsHoxYQaQA0pQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-SGVRsHoxYQaQA0pQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-SGVRsHoxYQaQA0pQ .rough-node .label,#mermaid-svg-SGVRsHoxYQaQA0pQ .node .label,#mermaid-svg-SGVRsHoxYQaQA0pQ .image-shape .label,#mermaid-svg-SGVRsHoxYQaQA0pQ .icon-shape .label{text-align:center;}#mermaid-svg-SGVRsHoxYQaQA0pQ .node.clickable{cursor:pointer;}#mermaid-svg-SGVRsHoxYQaQA0pQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .arrowheadPath{fill:#333333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-SGVRsHoxYQaQA0pQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SGVRsHoxYQaQA0pQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SGVRsHoxYQaQA0pQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SGVRsHoxYQaQA0pQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-SGVRsHoxYQaQA0pQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-SGVRsHoxYQaQA0pQ .cluster text{fill:#333;}#mermaid-svg-SGVRsHoxYQaQA0pQ .cluster span{color:#333;}#mermaid-svg-SGVRsHoxYQaQA0pQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-SGVRsHoxYQaQA0pQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SGVRsHoxYQaQA0pQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-SGVRsHoxYQaQA0pQ .icon-shape,#mermaid-svg-SGVRsHoxYQaQA0pQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SGVRsHoxYQaQA0pQ .icon-shape p,#mermaid-svg-SGVRsHoxYQaQA0pQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-SGVRsHoxYQaQA0pQ .icon-shape .label rect,#mermaid-svg-SGVRsHoxYQaQA0pQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SGVRsHoxYQaQA0pQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-SGVRsHoxYQaQA0pQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-SGVRsHoxYQaQA0pQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Yes
No
No
Yes
Yes
No
Yes
No
PopBatch 开始
unique = empty set
deltas = \[\]
遍历 i = 0..batchSize
i >= initialPopulationCount?
batchableitem.Type?
len(deltas)==0? → moveDelta
keyOf(item) → id
keyOf 出错?
unique.Has(id)?
unique.Insert(id)
moveDelta
结束收集
len(deltas)==1?
processSingle : processBatch
六、集成架构 --- Informer Pipeline 完整数据流
5.1 完整 Informer Pipeline
#mermaid-svg-bASuKxFCfVpqcdbm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bASuKxFCfVpqcdbm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bASuKxFCfVpqcdbm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bASuKxFCfVpqcdbm .error-icon{fill:#552222;}#mermaid-svg-bASuKxFCfVpqcdbm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bASuKxFCfVpqcdbm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bASuKxFCfVpqcdbm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bASuKxFCfVpqcdbm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bASuKxFCfVpqcdbm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bASuKxFCfVpqcdbm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bASuKxFCfVpqcdbm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bASuKxFCfVpqcdbm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bASuKxFCfVpqcdbm .marker.cross{stroke:#333333;}#mermaid-svg-bASuKxFCfVpqcdbm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bASuKxFCfVpqcdbm p{margin:0;}#mermaid-svg-bASuKxFCfVpqcdbm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bASuKxFCfVpqcdbm .cluster-label text{fill:#333;}#mermaid-svg-bASuKxFCfVpqcdbm .cluster-label span{color:#333;}#mermaid-svg-bASuKxFCfVpqcdbm .cluster-label span p{background-color:transparent;}#mermaid-svg-bASuKxFCfVpqcdbm .label text,#mermaid-svg-bASuKxFCfVpqcdbm span{fill:#333;color:#333;}#mermaid-svg-bASuKxFCfVpqcdbm .node rect,#mermaid-svg-bASuKxFCfVpqcdbm .node circle,#mermaid-svg-bASuKxFCfVpqcdbm .node ellipse,#mermaid-svg-bASuKxFCfVpqcdbm .node polygon,#mermaid-svg-bASuKxFCfVpqcdbm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bASuKxFCfVpqcdbm .rough-node .label text,#mermaid-svg-bASuKxFCfVpqcdbm .node .label text,#mermaid-svg-bASuKxFCfVpqcdbm .image-shape .label,#mermaid-svg-bASuKxFCfVpqcdbm .icon-shape .label{text-anchor:middle;}#mermaid-svg-bASuKxFCfVpqcdbm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bASuKxFCfVpqcdbm .rough-node .label,#mermaid-svg-bASuKxFCfVpqcdbm .node .label,#mermaid-svg-bASuKxFCfVpqcdbm .image-shape .label,#mermaid-svg-bASuKxFCfVpqcdbm .icon-shape .label{text-align:center;}#mermaid-svg-bASuKxFCfVpqcdbm .node.clickable{cursor:pointer;}#mermaid-svg-bASuKxFCfVpqcdbm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bASuKxFCfVpqcdbm .arrowheadPath{fill:#333333;}#mermaid-svg-bASuKxFCfVpqcdbm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bASuKxFCfVpqcdbm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bASuKxFCfVpqcdbm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bASuKxFCfVpqcdbm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bASuKxFCfVpqcdbm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bASuKxFCfVpqcdbm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bASuKxFCfVpqcdbm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bASuKxFCfVpqcdbm .cluster text{fill:#333;}#mermaid-svg-bASuKxFCfVpqcdbm .cluster span{color:#333;}#mermaid-svg-bASuKxFCfVpqcdbm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bASuKxFCfVpqcdbm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bASuKxFCfVpqcdbm rect.text{fill:none;stroke-width:0;}#mermaid-svg-bASuKxFCfVpqcdbm .icon-shape,#mermaid-svg-bASuKxFCfVpqcdbm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bASuKxFCfVpqcdbm .icon-shape p,#mermaid-svg-bASuKxFCfVpqcdbm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bASuKxFCfVpqcdbm .icon-shape .label rect,#mermaid-svg-bASuKxFCfVpqcdbm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bASuKxFCfVpqcdbm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bASuKxFCfVpqcdbm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bASuKxFCfVpqcdbm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} User
Processor
Store (cache/Indexer)
Controller
Queue (DeltaFIFO or RealFIFO)
Reflector
REST Client
API Server
kube-apiserver
GET /api/v1/namespaces/default/pods
GET /api/v1/namespaces/default/pods?watch=true
Reflector
ListAndWatch()
watchHandler()
resync()
Add/Update/Delete
Replace()
Pop() / PopBatch()
processLoop()
handleDeltas()
processDeltasInBatch()
cache.Add()
cache.Update()
cache.Delete()
cache.Replace()
ByIndex() / Index()
distribute()
processorListener
OnAdd/OnUpdate/OnDelete
WorkQueue.Add(key)
Worker: queue.Get() → reconcile()
5.2 两条队列路径:DeltaFIFO vs RealFIFO
#mermaid-svg-FB2RFvTjsSeT1PqU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FB2RFvTjsSeT1PqU .error-icon{fill:#552222;}#mermaid-svg-FB2RFvTjsSeT1PqU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FB2RFvTjsSeT1PqU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FB2RFvTjsSeT1PqU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FB2RFvTjsSeT1PqU .marker.cross{stroke:#333333;}#mermaid-svg-FB2RFvTjsSeT1PqU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FB2RFvTjsSeT1PqU p{margin:0;}#mermaid-svg-FB2RFvTjsSeT1PqU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FB2RFvTjsSeT1PqU .cluster-label text{fill:#333;}#mermaid-svg-FB2RFvTjsSeT1PqU .cluster-label span{color:#333;}#mermaid-svg-FB2RFvTjsSeT1PqU .cluster-label span p{background-color:transparent;}#mermaid-svg-FB2RFvTjsSeT1PqU .label text,#mermaid-svg-FB2RFvTjsSeT1PqU span{fill:#333;color:#333;}#mermaid-svg-FB2RFvTjsSeT1PqU .node rect,#mermaid-svg-FB2RFvTjsSeT1PqU .node circle,#mermaid-svg-FB2RFvTjsSeT1PqU .node ellipse,#mermaid-svg-FB2RFvTjsSeT1PqU .node polygon,#mermaid-svg-FB2RFvTjsSeT1PqU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FB2RFvTjsSeT1PqU .rough-node .label text,#mermaid-svg-FB2RFvTjsSeT1PqU .node .label text,#mermaid-svg-FB2RFvTjsSeT1PqU .image-shape .label,#mermaid-svg-FB2RFvTjsSeT1PqU .icon-shape .label{text-anchor:middle;}#mermaid-svg-FB2RFvTjsSeT1PqU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FB2RFvTjsSeT1PqU .rough-node .label,#mermaid-svg-FB2RFvTjsSeT1PqU .node .label,#mermaid-svg-FB2RFvTjsSeT1PqU .image-shape .label,#mermaid-svg-FB2RFvTjsSeT1PqU .icon-shape .label{text-align:center;}#mermaid-svg-FB2RFvTjsSeT1PqU .node.clickable{cursor:pointer;}#mermaid-svg-FB2RFvTjsSeT1PqU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FB2RFvTjsSeT1PqU .arrowheadPath{fill:#333333;}#mermaid-svg-FB2RFvTjsSeT1PqU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FB2RFvTjsSeT1PqU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FB2RFvTjsSeT1PqU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FB2RFvTjsSeT1PqU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FB2RFvTjsSeT1PqU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FB2RFvTjsSeT1PqU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FB2RFvTjsSeT1PqU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FB2RFvTjsSeT1PqU .cluster text{fill:#333;}#mermaid-svg-FB2RFvTjsSeT1PqU .cluster span{color:#333;}#mermaid-svg-FB2RFvTjsSeT1PqU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FB2RFvTjsSeT1PqU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FB2RFvTjsSeT1PqU rect.text{fill:none;stroke-width:0;}#mermaid-svg-FB2RFvTjsSeT1PqU .icon-shape,#mermaid-svg-FB2RFvTjsSeT1PqU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FB2RFvTjsSeT1PqU .icon-shape p,#mermaid-svg-FB2RFvTjsSeT1PqU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FB2RFvTjsSeT1PqU .icon-shape .label rect,#mermaid-svg-FB2RFvTjsSeT1PqU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FB2RFvTjsSeT1PqU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FB2RFvTjsSeT1PqU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FB2RFvTjsSeT1PqU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} RealFIFO 路径 (新)
DeltaFIFO 路径 (传统)
false
true
Reflector
Feature Gate
AtomicFIFO?
DeltaFIFO
Pop() → Deltas
handleDeltas()
逐个 Delta 处理
RealFIFO
(AtomicEvents=true)
PopBatch() → \[\]Delta
processDeltasInBatch()
原子 ReplacedAll 处理
Store / Indexer
Processor
5.3 handleDeltas vs processDeltasInBatch
DeltaFIFO 路径:handleDeltas(逐条处理)
go
// controller.go 中的 handleDeltas
func handleDeltas(obj interface{}, isInInitialList bool) error {
deltas := obj.(Deltas) // 一个 key 的所有 Delta
// 从最新到最旧遍历,找到最新的完整状态
for _, d := range deltas {
switch d.Type {
case Sync, Replaced, Added, Updated:
// 更新 Store
if exists, err := clientState.GetByKey(key); err == nil && exists {
clientState.Update(d.Object)
} else {
clientState.Add(d.Object)
}
case Deleted:
clientState.Delete(d.Object)
}
}
// 通知 Processor
processor.distribute(deltas.Newest(), isInInitialList)
}
RealFIFO 路径:processDeltasInBatch(批量处理)
go
func processDeltasInBatch(deltas []Delta, isInInitialList bool) error {
for _, d := range deltas {
switch d.Type {
case ReplacedAll:
info := d.Object.(ReplacedAllInfo)
// 原子替换整个 Store
clientState.Replace(info.Objects, info.ResourceVersion)
// 通知所有对象
for _, obj := range info.Objects {
processor.distribute(Delta{Type: Replaced, Object: obj}, isInInitialList)
}
case SyncAll:
// 原子 Resync
clientState.Resync()
case Bookmark:
// 只更新 RV,不触发事件
// 用于跟踪进度
default:
// 单条处理同 handleDeltas
}
}
}
六、组件间调用关系详解
6.1 SharedInformer → Controller → Reflector → Queue → Store 调用链
EventHandler Processor Store (cache) Queue (FIFO) Reflector Controller SharedInformer EventHandler Processor Store (cache) Queue (FIFO) Reflector Controller SharedInformer #mermaid-svg-riz6FaH1USohOPjc{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-riz6FaH1USohOPjc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-riz6FaH1USohOPjc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-riz6FaH1USohOPjc .error-icon{fill:#552222;}#mermaid-svg-riz6FaH1USohOPjc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-riz6FaH1USohOPjc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-riz6FaH1USohOPjc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-riz6FaH1USohOPjc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-riz6FaH1USohOPjc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-riz6FaH1USohOPjc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-riz6FaH1USohOPjc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-riz6FaH1USohOPjc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-riz6FaH1USohOPjc .marker.cross{stroke:#333333;}#mermaid-svg-riz6FaH1USohOPjc svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-riz6FaH1USohOPjc p{margin:0;}#mermaid-svg-riz6FaH1USohOPjc .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-riz6FaH1USohOPjc text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-riz6FaH1USohOPjc .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-riz6FaH1USohOPjc .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-riz6FaH1USohOPjc .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-riz6FaH1USohOPjc .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-riz6FaH1USohOPjc #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-riz6FaH1USohOPjc .sequenceNumber{fill:white;}#mermaid-svg-riz6FaH1USohOPjc #sequencenumber{fill:#333;}#mermaid-svg-riz6FaH1USohOPjc #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-riz6FaH1USohOPjc .messageText{fill:#333;stroke:none;}#mermaid-svg-riz6FaH1USohOPjc .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-riz6FaH1USohOPjc .labelText,#mermaid-svg-riz6FaH1USohOPjc .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-riz6FaH1USohOPjc .loopText,#mermaid-svg-riz6FaH1USohOPjc .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-riz6FaH1USohOPjc .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-riz6FaH1USohOPjc .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-riz6FaH1USohOPjc .noteText,#mermaid-svg-riz6FaH1USohOPjc .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-riz6FaH1USohOPjc .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-riz6FaH1USohOPjc .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-riz6FaH1USohOPjc .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-riz6FaH1USohOPjc .actorPopupMenu{position:absolute;}#mermaid-svg-riz6FaH1USohOPjc .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-riz6FaH1USohOPjc .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-riz6FaH1USohOPjc .actor-man circle,#mermaid-svg-riz6FaH1USohOPjc line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-riz6FaH1USohOPjc :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 启动 processLoop goroutine ListAndWatch loopprocessLoop HasSynced = Store.HasSynced && Controller.HasSynced RunWithContext(ctx)RunWithContext(ctx)Replace(initialList, rv)Add/Update/Delete (watch events)Pop(processFunc)DeltasAdd/Update/Deletedistribute(notification)OnAdd/OnUpdate/OnDeleteHasSynced()HasSynced()true (initialPopulationCount==0)true
6.2 Processor 事件分发
EventHandler 2 EventHandler 1 Listener 2 Listener 1 sharedProcessor Controller EventHandler 2 EventHandler 1 Listener 2 Listener 1 sharedProcessor Controller #mermaid-svg-LCjkDaVvj9KkHKt8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LCjkDaVvj9KkHKt8 .error-icon{fill:#552222;}#mermaid-svg-LCjkDaVvj9KkHKt8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LCjkDaVvj9KkHKt8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LCjkDaVvj9KkHKt8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LCjkDaVvj9KkHKt8 .marker.cross{stroke:#333333;}#mermaid-svg-LCjkDaVvj9KkHKt8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LCjkDaVvj9KkHKt8 p{margin:0;}#mermaid-svg-LCjkDaVvj9KkHKt8 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LCjkDaVvj9KkHKt8 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-LCjkDaVvj9KkHKt8 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-LCjkDaVvj9KkHKt8 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-LCjkDaVvj9KkHKt8 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-LCjkDaVvj9KkHKt8 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-LCjkDaVvj9KkHKt8 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-LCjkDaVvj9KkHKt8 .sequenceNumber{fill:white;}#mermaid-svg-LCjkDaVvj9KkHKt8 #sequencenumber{fill:#333;}#mermaid-svg-LCjkDaVvj9KkHKt8 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-LCjkDaVvj9KkHKt8 .messageText{fill:#333;stroke:none;}#mermaid-svg-LCjkDaVvj9KkHKt8 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LCjkDaVvj9KkHKt8 .labelText,#mermaid-svg-LCjkDaVvj9KkHKt8 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-LCjkDaVvj9KkHKt8 .loopText,#mermaid-svg-LCjkDaVvj9KkHKt8 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-LCjkDaVvj9KkHKt8 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-LCjkDaVvj9KkHKt8 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-LCjkDaVvj9KkHKt8 .noteText,#mermaid-svg-LCjkDaVvj9KkHKt8 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-LCjkDaVvj9KkHKt8 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LCjkDaVvj9KkHKt8 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LCjkDaVvj9KkHKt8 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-LCjkDaVvj9KkHKt8 .actorPopupMenu{position:absolute;}#mermaid-svg-LCjkDaVvj9KkHKt8 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-LCjkDaVvj9KkHKt8 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-LCjkDaVvj9KkHKt8 .actor-man circle,#mermaid-svg-LCjkDaVvj9KkHKt8 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-LCjkDaVvj9KkHKt8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} par并行分发 par各 Listener 独立 pop distribute(notification)add(notification)add(notification)pop() → 取出 notificationOnAdd(obj)pop() → 取出 notificationOnAdd(obj)
6.3 Resync 机制
EventHandler Processor Store (cache) DeltaFIFO Reflector Resync Timer EventHandler Processor Store (cache) DeltaFIFO Reflector Resync Timer #mermaid-svg-ocvScOiLzY1J9pSQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ocvScOiLzY1J9pSQ .error-icon{fill:#552222;}#mermaid-svg-ocvScOiLzY1J9pSQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ocvScOiLzY1J9pSQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ocvScOiLzY1J9pSQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ocvScOiLzY1J9pSQ .marker.cross{stroke:#333333;}#mermaid-svg-ocvScOiLzY1J9pSQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ocvScOiLzY1J9pSQ p{margin:0;}#mermaid-svg-ocvScOiLzY1J9pSQ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ocvScOiLzY1J9pSQ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-ocvScOiLzY1J9pSQ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ocvScOiLzY1J9pSQ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-ocvScOiLzY1J9pSQ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-ocvScOiLzY1J9pSQ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-ocvScOiLzY1J9pSQ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-ocvScOiLzY1J9pSQ .sequenceNumber{fill:white;}#mermaid-svg-ocvScOiLzY1J9pSQ #sequencenumber{fill:#333;}#mermaid-svg-ocvScOiLzY1J9pSQ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-ocvScOiLzY1J9pSQ .messageText{fill:#333;stroke:none;}#mermaid-svg-ocvScOiLzY1J9pSQ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ocvScOiLzY1J9pSQ .labelText,#mermaid-svg-ocvScOiLzY1J9pSQ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-ocvScOiLzY1J9pSQ .loopText,#mermaid-svg-ocvScOiLzY1J9pSQ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-ocvScOiLzY1J9pSQ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ocvScOiLzY1J9pSQ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-ocvScOiLzY1J9pSQ .noteText,#mermaid-svg-ocvScOiLzY1J9pSQ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-ocvScOiLzY1J9pSQ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ocvScOiLzY1J9pSQ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ocvScOiLzY1J9pSQ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ocvScOiLzY1J9pSQ .actorPopupMenu{position:absolute;}#mermaid-svg-ocvScOiLzY1J9pSQ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-ocvScOiLzY1J9pSQ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ocvScOiLzY1J9pSQ .actor-man circle,#mermaid-svg-ocvScOiLzY1J9pSQ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-ocvScOiLzY1J9pSQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 如果 key 已在队列中则忽略 loop每个 key 强制重新处理(即使对象未变化) resyncCh 触发List() → 所有对象AddIfNotPresent(key, Sync)Pop → Sync DeltaOnUpdate(oldObj, newObj)
七、关键不变量与设计原则
7.1 核心不变量
| # | 不变量 | 保证机制 |
|---|---|---|
| 1 | Store 中同 key 只有一个对象 | cache 使用 map 存储 |
| 2 | DeltaFIFO 中同 key 最多一个 queue 条目 | items map 去重 |
| 3 | RealFIFO 的 Delta 按序排列 | items 是有序 slice |
| 4 | Pop 返回的 Deltas 按时间排序 | DeltaFIFO append 保证 |
| 5 | 同 item 不被并发处理 | DeltaFIFO Pop 原子性 |
| 6 | HasSynced 只在初始 Pop 完成后为 true | initialPopulationCount 追踪 |
| 7 | EventHandler 串行调用 | processorListener 单 goroutine pop |
| 8 | InformerName 全局唯一 | informerNameRegistry + sync.Once |
| 9 | ExpirationCache 惰性过期 | getOrExpire 加写锁 |
| 10 | Heap 堆序不变 | heap.Fix/heap.Push/heap.Pop 维护 |
7.2 线程安全保证
| 组件 | 锁机制 | 说明 |
|---|---|---|
| cache | threadSafeMap.RWMutex | 所有操作加锁 |
| DeltaFIFO | sync.Mutex | 所有操作加锁 |
| RealFIFO | sync.RWMutex + sync.Cond | Pop 阻塞等待 |
| Heap | sync.RWMutex + sync.Cond | Pop 阻塞等待 |
| ExpirationCache | threadSafeMap lock + expirationLock | 双重锁 |
| MutationCache | sync.Mutex | 所有操作加锁 |
| sharedProcessor | listenersLock | 保护 listeners 列表 |
| processorListener | 无锁(单 goroutine 消费) | addCh → ring.Buffer → nextCh |
7.3 错误处理策略
| 场景 | 策略 |
|---|---|
| Reflector List 失败 | 重试(wait.BackoffUntil + 1s 基础间隔) |
| Reflector Watch 断开 | 重新 ListAndWatch |
| Pop 处理失败 (DeltaFIFO) | AddIfNotPresent 重新入队 |
| Pop 处理失败 (RealFIFO) | 不重新入队(无去重) |
| MutationDetector 检测到修改 | panic(数据已不可信) |
| KeyFunc 返回错误 | 返回 KeyError,不添加到队列 |
| TransformFunc 返回错误 | 返回错误,不添加到队列 |
八、设计模式总结
8.1 16 个核心设计模式
| # | 模式 | 体现 | 文件 |
|---|---|---|---|
| 1 | 观察者模式 | sharedProcessor 扇出给多个 Listener | shared_informer.go |
| 2 | 生产者-消费者 | Reflector 生产 → FIFO → Controller 消费 | reflector.go, controller.go |
| 3 | 装饰器模式 | UndeltaStore 包装 Store | undelta_store.go |
| 4 | 策略模式 | KeyFunc/LessFunc/ExpirationPolicy 可注入 | store.go, heap.go, expiration_cache.go |
| 5 | 工厂方法 | NewStore/NewIndexer/NewHeap/NewTTLStore | 多文件 |
| 6 | 单例注册 | InformerName 全局注册表 | identity.go |
| 7 | 延迟求值 | synctrack.Lazy | synctrack/lazy.go |
| 8 | 原子计数 | SingleFileTracker atomic int64 | synctrack/synctrack.go |
| 9 | TTL 过期 | ExpirationCache + TTLPolicy | expiration_cache.go |
| 10 | LRU 叠层 | MutationCache = Store + LRU | mutation_cache.go |
| 11 | 深拷贝检测 | MutationDetector 深拷贝对比 | mutation_detector.go |
| 12 | 双路径处理 | Pop(单条) vs PopBatch(批量) | the_real_fifo.go |
| 13 | 条件变量 | RealFIFO/Heap 用 sync.Cond 阻塞 Pop | the_real_fifo.go, heap.go |
| 14 | 环形缓冲 | processorListener ring.Buffer 削峰 | shared_informer.go |
| 15 | 适配器模式 | listerWrapper/WatcherWrapper 适配旧接口 | listwatch.go |
| 16 | 三集合去重 | WorkQueue dirty+queue+processing | (util/workqueue) |
8.2 组件协作关系总览
#mermaid-svg-mbAgzg81ZAu6HTGa{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mbAgzg81ZAu6HTGa .error-icon{fill:#552222;}#mermaid-svg-mbAgzg81ZAu6HTGa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mbAgzg81ZAu6HTGa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mbAgzg81ZAu6HTGa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mbAgzg81ZAu6HTGa .marker.cross{stroke:#333333;}#mermaid-svg-mbAgzg81ZAu6HTGa svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mbAgzg81ZAu6HTGa p{margin:0;}#mermaid-svg-mbAgzg81ZAu6HTGa .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mbAgzg81ZAu6HTGa .cluster-label text{fill:#333;}#mermaid-svg-mbAgzg81ZAu6HTGa .cluster-label span{color:#333;}#mermaid-svg-mbAgzg81ZAu6HTGa .cluster-label span p{background-color:transparent;}#mermaid-svg-mbAgzg81ZAu6HTGa .label text,#mermaid-svg-mbAgzg81ZAu6HTGa span{fill:#333;color:#333;}#mermaid-svg-mbAgzg81ZAu6HTGa .node rect,#mermaid-svg-mbAgzg81ZAu6HTGa .node circle,#mermaid-svg-mbAgzg81ZAu6HTGa .node ellipse,#mermaid-svg-mbAgzg81ZAu6HTGa .node polygon,#mermaid-svg-mbAgzg81ZAu6HTGa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mbAgzg81ZAu6HTGa .rough-node .label text,#mermaid-svg-mbAgzg81ZAu6HTGa .node .label text,#mermaid-svg-mbAgzg81ZAu6HTGa .image-shape .label,#mermaid-svg-mbAgzg81ZAu6HTGa .icon-shape .label{text-anchor:middle;}#mermaid-svg-mbAgzg81ZAu6HTGa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mbAgzg81ZAu6HTGa .rough-node .label,#mermaid-svg-mbAgzg81ZAu6HTGa .node .label,#mermaid-svg-mbAgzg81ZAu6HTGa .image-shape .label,#mermaid-svg-mbAgzg81ZAu6HTGa .icon-shape .label{text-align:center;}#mermaid-svg-mbAgzg81ZAu6HTGa .node.clickable{cursor:pointer;}#mermaid-svg-mbAgzg81ZAu6HTGa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mbAgzg81ZAu6HTGa .arrowheadPath{fill:#333333;}#mermaid-svg-mbAgzg81ZAu6HTGa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mbAgzg81ZAu6HTGa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mbAgzg81ZAu6HTGa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mbAgzg81ZAu6HTGa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mbAgzg81ZAu6HTGa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mbAgzg81ZAu6HTGa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mbAgzg81ZAu6HTGa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mbAgzg81ZAu6HTGa .cluster text{fill:#333;}#mermaid-svg-mbAgzg81ZAu6HTGa .cluster span{color:#333;}#mermaid-svg-mbAgzg81ZAu6HTGa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mbAgzg81ZAu6HTGa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mbAgzg81ZAu6HTGa rect.text{fill:none;stroke-width:0;}#mermaid-svg-mbAgzg81ZAu6HTGa .icon-shape,#mermaid-svg-mbAgzg81ZAu6HTGa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mbAgzg81ZAu6HTGa .icon-shape p,#mermaid-svg-mbAgzg81ZAu6HTGa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mbAgzg81ZAu6HTGa .icon-shape .label rect,#mermaid-svg-mbAgzg81ZAu6HTGa .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mbAgzg81ZAu6HTGa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mbAgzg81ZAu6HTGa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mbAgzg81ZAu6HTGa :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 重试控制
命名与指标
同步追踪
查询
安全与调试
辅助缓存
核心 Pipeline
ListWatch
Reflector
DeltaFIFO / RealFIFO
Controller
cache (Store + Indexer)
sharedProcessor
ExpirationCache
(TTL 自动过期)
Heap
(优先队列)
MutationCache
(LRU 叠层)
UndeltaStore
(增量→全量)
MutationDetector
(深拷贝检测)
GenericLister
(Namespace+Label)
AsyncTracker
(多 Worker)
SingleFileTracker
(单线程)
LazyT
(延迟求值)
InformerName
(全局注册)
EventHandlerName
(函数名提取)
RetryWithDeadline
(带截止期限)
8.3 源文件依赖矩阵
#mermaid-svg-YO5cAUAtkYC26LMF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-YO5cAUAtkYC26LMF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YO5cAUAtkYC26LMF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YO5cAUAtkYC26LMF .error-icon{fill:#552222;}#mermaid-svg-YO5cAUAtkYC26LMF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YO5cAUAtkYC26LMF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YO5cAUAtkYC26LMF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YO5cAUAtkYC26LMF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YO5cAUAtkYC26LMF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YO5cAUAtkYC26LMF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YO5cAUAtkYC26LMF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YO5cAUAtkYC26LMF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YO5cAUAtkYC26LMF .marker.cross{stroke:#333333;}#mermaid-svg-YO5cAUAtkYC26LMF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YO5cAUAtkYC26LMF p{margin:0;}#mermaid-svg-YO5cAUAtkYC26LMF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YO5cAUAtkYC26LMF .cluster-label text{fill:#333;}#mermaid-svg-YO5cAUAtkYC26LMF .cluster-label span{color:#333;}#mermaid-svg-YO5cAUAtkYC26LMF .cluster-label span p{background-color:transparent;}#mermaid-svg-YO5cAUAtkYC26LMF .label text,#mermaid-svg-YO5cAUAtkYC26LMF span{fill:#333;color:#333;}#mermaid-svg-YO5cAUAtkYC26LMF .node rect,#mermaid-svg-YO5cAUAtkYC26LMF .node circle,#mermaid-svg-YO5cAUAtkYC26LMF .node ellipse,#mermaid-svg-YO5cAUAtkYC26LMF .node polygon,#mermaid-svg-YO5cAUAtkYC26LMF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YO5cAUAtkYC26LMF .rough-node .label text,#mermaid-svg-YO5cAUAtkYC26LMF .node .label text,#mermaid-svg-YO5cAUAtkYC26LMF .image-shape .label,#mermaid-svg-YO5cAUAtkYC26LMF .icon-shape .label{text-anchor:middle;}#mermaid-svg-YO5cAUAtkYC26LMF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YO5cAUAtkYC26LMF .rough-node .label,#mermaid-svg-YO5cAUAtkYC26LMF .node .label,#mermaid-svg-YO5cAUAtkYC26LMF .image-shape .label,#mermaid-svg-YO5cAUAtkYC26LMF .icon-shape .label{text-align:center;}#mermaid-svg-YO5cAUAtkYC26LMF .node.clickable{cursor:pointer;}#mermaid-svg-YO5cAUAtkYC26LMF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YO5cAUAtkYC26LMF .arrowheadPath{fill:#333333;}#mermaid-svg-YO5cAUAtkYC26LMF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YO5cAUAtkYC26LMF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YO5cAUAtkYC26LMF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YO5cAUAtkYC26LMF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YO5cAUAtkYC26LMF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YO5cAUAtkYC26LMF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YO5cAUAtkYC26LMF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YO5cAUAtkYC26LMF .cluster text{fill:#333;}#mermaid-svg-YO5cAUAtkYC26LMF .cluster span{color:#333;}#mermaid-svg-YO5cAUAtkYC26LMF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-YO5cAUAtkYC26LMF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YO5cAUAtkYC26LMF rect.text{fill:none;stroke-width:0;}#mermaid-svg-YO5cAUAtkYC26LMF .icon-shape,#mermaid-svg-YO5cAUAtkYC26LMF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YO5cAUAtkYC26LMF .icon-shape p,#mermaid-svg-YO5cAUAtkYC26LMF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YO5cAUAtkYC26LMF .icon-shape .label rect,#mermaid-svg-YO5cAUAtkYC26LMF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YO5cAUAtkYC26LMF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YO5cAUAtkYC26LMF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YO5cAUAtkYC26LMF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} shared_informer.go
controller.go
reflector.go
delta_fifo.go
the_real_fifo.go
fifo.go
store.go
thread_safe_store.go
index.go
listwatch.go
listers.go
expiration_cache.go
heap.go
mutation_cache.go
undelta_store.go
mutation_detector.go
identity.go
synctrack/
retry_with_deadline.go
object-names.go
event_handler_name.go
*_metrics.go
九、全模块源文件清单
| 文件 | 行数 | 核心内容 | 分析深度 |
|---|---|---|---|
shared_informer.go |
1409 | SharedInformer、sharedProcessor、processorListener | ✅ 详见独立目录 |
reflector.go |
1333 | Reflector、ListAndWatch、watchHandler | ✅ 详见独立目录 |
controller.go |
878 | Controller、processLoop、handleDeltas | ✅ 详见独立目录 |
the_real_fifo.go |
859 | RealFIFO、PopBatch、AtomicEvents | ✅ 本文档 |
delta_fifo.go |
800 | DeltaFIFO、Pop、Replace、Resync | ✅ 详见独立目录 |
thread_safe_store.go |
552 | threadSafeMap、storeIndex | ✅ 详见独立目录 |
store.go |
439 | cache、Store 构造、KeyFunc | ✅ 详见独立目录 |
listwatch.go |
312 | ListWatch、ListerWatcher 接口 | ✅ 本文档 |
heap.go |
322 | Heap、heapData、优先队列 | ✅ 本文档 |
mutation_cache.go |
264 | mutationCache、LRU 叠层 | ✅ 本文档 |
expiration_cache.go |
224 | ExpirationCache、TTLPolicy | ✅ 本文档 |
identity.go |
217 | InformerName、InformerNameAndResource | ✅ 本文档 |
synctrack/synctrack.go |
214 | AsyncTracker、SingleFileTracker | ✅ 本文档 |
listers.go |
184 | GenericLister、ListAllByNamespace | ✅ 本文档 |
mutation_detector.go |
167 | MutationDetector、深拷贝对比 | ✅ 本文档 |
fifo.go |
345 | FIFO 基础队列、Queue 接口 | ✅ 详见独立目录 |
undelta_store.go |
89 | UndeltaStore、PushFunc | ✅ 本文档 |
synctrack/lazy.go |
83 | LazyT 延迟求值 | ✅ 本文档 |
retry_with_deadline.go |
78 | RetryWithDeadline | ✅ 本文档 |
object-names.go |
65 | ObjectName 值类型 | ✅ 本文档 |
event_handler_name.go |
121 | EventHandler 命名 | ✅ 本文档 |
fifo_metrics.go |
122 | FIFO 指标 | ✅ 本文档 |
index.go |
100 | IndexFunc、Indexers 定义 | ✅ 详见独立目录 |
fake_custom_store.go |
102 | FakeCustomStore | 略(测试) |
reflector_metrics.go |
95 | Reflector 指标 | ✅ 详见独立目录 |
doc.go |
24 | 包文档 | 略 |
expiration_cache_fakes.go |
57 | 测试假实现 | 略(测试) |
reflector_data_consistency_detector.go |
43 | 数据一致性检测 | ✅ 详见独立目录 |
| 合计 | ~9789 | --- | --- |