type eventType … func (e eventType) String() string { … } const addEvent … const updateEvent … const deleteEvent … type event … type GraphBuilder … type monitor … // Run is intended to be called in a goroutine. Multiple calls of this is an // error. func (m *monitor) Run() { … } type monitors … func NewDependencyGraphBuilder( ctx context.Context, metadataClient metadata.Interface, mapper meta.ResettableRESTMapper, ignoredResources map[schema.GroupResource]struct{ … } func (gb *GraphBuilder) controllerFor(logger klog.Logger, resource schema.GroupVersionResource, kind schema.GroupVersionKind) (cache.Controller, cache.Store, error) { … } // syncMonitors rebuilds the monitor set according to the supplied resources, // creating or deleting monitors as necessary. It will return any error // encountered, but will make an attempt to create a monitor for each resource // instead of immediately exiting on an error. It may be called before or after // Run. Monitors are NOT started as part of the sync. To ensure all existing // monitors are started, call startMonitors. func (gb *GraphBuilder) syncMonitors(logger klog.Logger, resources map[schema.GroupVersionResource]struct{ … } // startMonitors ensures the current set of monitors are running. Any newly // started monitors will also cause shared informers to be started. // // If called before Run, startMonitors does nothing (as there is no stop channel // to support monitor/informer execution). func (gb *GraphBuilder) startMonitors(logger klog.Logger) { … } // IsResourceSynced returns true if a monitor exists for the given resource and has synced func (gb *GraphBuilder) IsResourceSynced(resource schema.GroupVersionResource) bool { … } // IsSynced returns true if any monitors exist AND all those monitors' // controllers HasSynced functions return true. This means IsSynced could return // true at one time, and then later return false if all monitors were // reconstructed. func (gb *GraphBuilder) IsSynced(logger klog.Logger) bool { … } // Run sets the stop channel and starts monitor execution until stopCh is // closed. Any running monitors will be stopped before Run returns. func (gb *GraphBuilder) Run(ctx context.Context) { … } var ignoredResources … // DefaultIgnoredResources returns the default set of resources that the garbage collector controller // should ignore. This is exposed so downstream integrators can have access to the defaults, and add // to them as necessary when constructing the controller. func DefaultIgnoredResources() map[schema.GroupResource]struct{ … } // enqueueVirtualDeleteEvent is used to add a virtual delete event to be processed for virtual nodes // once it is determined they do not have backing objects in storage func (gb *GraphBuilder) enqueueVirtualDeleteEvent(ref objectReference) { … } // addDependentToOwners adds n to owners' dependents list. If the owner does not // exist in the gb.uidToNode yet, a "virtual" node will be created to represent // the owner. The "virtual" node will be enqueued to the attemptToDelete, so that // attemptToDeleteItem() will verify if the owner exists according to the API server. func (gb *GraphBuilder) addDependentToOwners(logger klog.Logger, n *node, owners []metav1.OwnerReference) { … } func (gb *GraphBuilder) reportInvalidNamespaceOwnerRef(n *node, invalidOwnerUID types.UID) { … } // insertNode insert the node to gb.uidToNode; then it finds all owners as listed // in n.owners, and adds the node to their dependents list. func (gb *GraphBuilder) insertNode(logger klog.Logger, n *node) { … } // removeDependentFromOwners remove n from owners' dependents list. func (gb *GraphBuilder) removeDependentFromOwners(n *node, owners []metav1.OwnerReference) { … } // removeNode removes the node from gb.uidToNode, then finds all // owners as listed in n.owners, and removes n from their dependents list. func (gb *GraphBuilder) removeNode(n *node) { … } type ownerRefPair … // TODO: profile this function to see if a naive N^2 algorithm performs better // when the number of references is small. func referencesDiffs(old []metav1.OwnerReference, new []metav1.OwnerReference) (added []metav1.OwnerReference, removed []metav1.OwnerReference, changed []ownerRefPair) { … } func deletionStartsWithFinalizer(oldObj interface{ … } func beingDeleted(accessor metav1.Object) bool { … } func hasDeleteDependentsFinalizer(accessor metav1.Object) bool { … } func hasOrphanFinalizer(accessor metav1.Object) bool { … } func hasFinalizer(accessor metav1.Object, matchingFinalizer string) bool { … } // this function takes newAccessor directly because the caller already // instantiates an accessor for the newObj. func startsWaitingForDependentsDeleted(oldObj interface{ … } // this function takes newAccessor directly because the caller already // instantiates an accessor for the newObj. func startsWaitingForDependentsOrphaned(oldObj interface{ … } // if an blocking ownerReference points to an object gets removed, or gets set to // "BlockOwnerDeletion=false", add the object to the attemptToDelete queue. func (gb *GraphBuilder) addUnblockedOwnersToDeleteQueue(logger klog.Logger, removed []metav1.OwnerReference, changed []ownerRefPair) { … } func (gb *GraphBuilder) processTransitions(logger klog.Logger, oldObj interface{ … } func (gb *GraphBuilder) runProcessGraphChanges(logger klog.Logger) { … } func identityFromEvent(event *event, accessor metav1.Object) objectReference { … } // Dequeueing an event from graphChanges, updating graph, populating dirty_queue. func (gb *GraphBuilder) processGraphChanges(logger klog.Logger) bool { … } // partitionDependents divides the provided dependents into a list which have an ownerReference matching the provided identity, // and ones which have an ownerReference for the given uid that do not match the provided identity. // Note that a dependent with multiple ownerReferences for the target uid can end up in both lists. func partitionDependents(dependents []*node, matchOwnerIdentity objectReference) (matching, nonmatching []*node) { … } func referenceLessThan(a, b objectReference) bool { … } // getAlternateOwnerIdentity searches deps for owner references which match // verifiedAbsentIdentity.UID but differ in apiVersion/kind/name or namespace. // The first that follows verifiedAbsentIdentity (according to referenceLessThan) is returned. // If none follow verifiedAbsentIdentity, the first (according to referenceLessThan) is returned. // If no alternate identities are found, nil is returned. func getAlternateOwnerIdentity(deps []*node, verifiedAbsentIdentity objectReference) *objectReference { … } func (gb *GraphBuilder) GetGraphResources() ( attemptToDelete workqueue.TypedRateLimitingInterface[*node], attemptToOrphan workqueue.TypedRateLimitingInterface[*node], absentOwnerCache *ReferenceCache, ) { … } type Monitor … // GetMonitor returns a monitor for the given resource. // If the monitor is not synced, it will return an error and the monitor to allow the caller to decide whether to retry. // If the monitor is not found, it will return only an error. func (gb *GraphBuilder) GetMonitor(ctx context.Context, resource schema.GroupVersionResource) (*Monitor, error) { … } func (gb *GraphBuilder) Name() string { … }