const ResourceResyncTime … type GarbageCollector … var _ … var _ … // NewGarbageCollector creates a new GarbageCollector. func NewGarbageCollector( ctx context.Context, kubeClient clientset.Interface, metadataClient metadata.Interface, mapper meta.ResettableRESTMapper, ignoredResources map[schema.GroupResource]struct{ … } func NewComposedGarbageCollector( ctx context.Context, kubeClient clientset.Interface, metadataClient metadata.Interface, mapper meta.ResettableRESTMapper, graphBuilder *GraphBuilder, ) (*GarbageCollector, error) { … } // resyncMonitors starts or stops resource monitors as needed to ensure that all // (and only) those resources present in the map are monitored. func (gc *GarbageCollector) resyncMonitors(logger klog.Logger, deletableResources map[schema.GroupVersionResource]struct{ … } // Run starts garbage collector workers. func (gc *GarbageCollector) Run(ctx context.Context, workers int, initialSyncTimeout time.Duration) { … } // Sync periodically resyncs the garbage collector when new resources are // observed from discovery. When new resources are detected, it will reset // gc.restMapper, and resync the monitors. // // Note that discoveryClient should NOT be shared with gc.restMapper, otherwise // the mapper's underlying discovery client will be unnecessarily reset during // the course of detecting new resources. func (gc *GarbageCollector) Sync(ctx context.Context, discoveryClient discovery.ServerResourcesInterface, period time.Duration) { … } // printDiff returns a human-readable summary of what resources were added and removed func printDiff(oldResources, newResources map[schema.GroupVersionResource]struct{ … } // waitForStopOrTimeout returns a stop channel that closes when the provided stop channel closes or when the specified timeout is reached func waitForStopOrTimeout(stopCh <-chan struct{ … } // IsSynced returns true if dependencyGraphBuilder is synced. func (gc *GarbageCollector) IsSynced(logger klog.Logger) bool { … } func (gc *GarbageCollector) runAttemptToDeleteWorker(ctx context.Context) { … } var enqueuedVirtualDeleteEventErr … var namespacedOwnerOfClusterScopedObjectErr … func (gc *GarbageCollector) processAttemptToDeleteWorker(ctx context.Context) bool { … } type workQueueItemAction … const requeueItem … const forgetItem … func (gc *GarbageCollector) attemptToDeleteWorker(ctx context.Context, item interface{ … } // isDangling check if a reference is pointing to an object that doesn't exist. // If isDangling looks up the referenced object at the API server, it also // returns its latest state. func (gc *GarbageCollector) isDangling(ctx context.Context, reference metav1.OwnerReference, item *node) ( dangling bool, owner *metav1.PartialObjectMetadata, err error) { … } // classify the latestReferences to three categories: // solid: the owner exists, and is not "waitingForDependentsDeletion" // dangling: the owner does not exist // waitingForDependentsDeletion: the owner exists, its deletionTimestamp is non-nil, and it has // FinalizerDeletingDependents // This function communicates with the server. func (gc *GarbageCollector) classifyReferences(ctx context.Context, item *node, latestReferences []metav1.OwnerReference) ( solid, dangling, waitingForDependentsDeletion []metav1.OwnerReference, err error) { … } func ownerRefsToUIDs(refs []metav1.OwnerReference) []types.UID { … } // attemptToDeleteItem looks up the live API object associated with the node, // and issues a delete IFF the uid matches, the item is not blocked on deleting dependents, // and all owner references are dangling. // // if the API get request returns a NotFound error, or the retrieved item's uid does not match, // a virtual delete event for the node is enqueued and enqueuedVirtualDeleteEventErr is returned. func (gc *GarbageCollector) attemptToDeleteItem(ctx context.Context, item *node) error { … } // process item that's waiting for its dependents to be deleted func (gc *GarbageCollector) processDeletingDependentsItem(logger klog.Logger, item *node) error { … } // dependents are copies of pointers to the owner's dependents, they don't need to be locked. func (gc *GarbageCollector) orphanDependents(logger klog.Logger, owner objectReference, dependents []*node) error { … } func (gc *GarbageCollector) runAttemptToOrphanWorker(logger klog.Logger) { … } // processAttemptToOrphanWorker dequeues a node from the attemptToOrphan, then finds its // dependents based on the graph maintained by the GC, then removes it from the // OwnerReferences of its dependents, and finally updates the owner to remove // the "Orphan" finalizer. The node is added back into the attemptToOrphan if any of // these steps fail. func (gc *GarbageCollector) processAttemptToOrphanWorker(logger klog.Logger) bool { … } func (gc *GarbageCollector) attemptToOrphanWorker(logger klog.Logger, item interface{ … } // *FOR TEST USE ONLY* // GraphHasUID returns if the GraphBuilder has a particular UID store in its // uidToNode graph. It's useful for debugging. // This method is used by integration tests. func (gc *GarbageCollector) GraphHasUID(u types.UID) bool { … } // GetDeletableResources returns all resources from discoveryClient that the // garbage collector should recognize and work with. More specifically, all // preferred resources which support the 'delete', 'list', and 'watch' verbs. // // If an error was encountered fetching resources from the server, // it is included as well, along with any resources that were successfully resolved. // // All discovery errors are considered temporary. Upon encountering any error, // GetDeletableResources will log and return any discovered resources it was // able to process (which may be none). func GetDeletableResources(logger klog.Logger, discoveryClient discovery.ServerResourcesInterface) (map[schema.GroupVersionResource]struct{ … } func (gc *GarbageCollector) Name() string { … } // GetDependencyGraphBuilder return graph builder which is particularly helpful for testing where controllerContext is not available func (gc *GarbageCollector) GetDependencyGraphBuilder() *GraphBuilder { … }