From 1b8aded77b1ffa2714c960280d2aebf772827e6d Mon Sep 17 00:00:00 2001 From: googs1025 Date: Mon, 30 Sep 2024 09:38:10 +0800 Subject: [PATCH] chore(leader-election): modify leader-election comment to OnStoppedLeading callback is always called when the LeaderElector exits, even if it did not start leading. Kubernetes-commit: 7d2fbc7cfd49bca7d58160ed25dfd1f838629bb9 --- examples/leader-election/main.go | 17 ++++++++++++++++- tools/leaderelection/leaderelection.go | 5 ++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/examples/leader-election/main.go b/examples/leader-election/main.go index 6fdd75c1..bec03c76 100644 --- a/examples/leader-election/main.go +++ b/examples/leader-election/main.go @@ -21,6 +21,7 @@ import ( "flag" "os" "os/signal" + "sync/atomic" "syscall" "time" @@ -57,6 +58,7 @@ func main() { var leaseLockName string var leaseLockNamespace string var id string + var startedLeading atomic.Bool flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file") flag.StringVar(&id, "id", uuid.New().String(), "the holder identity name") @@ -135,11 +137,24 @@ func main() { OnStartedLeading: func(ctx context.Context) { // we're notified when we start - this is where you would // usually put your code + startedLeading.Store(true) run(ctx) }, OnStoppedLeading: func() { - // we can do cleanup here + // we can do cleanup here, but note that this callback is always called + // when the LeaderElector exits, even if it did not start leading. + // Therefore, we should check if we actually started leading before + // performing any cleanup operations to avoid unexpected behavior. klog.Infof("leader lost: %s", id) + + // Example check to ensure we only perform cleanup if we actually started leading + if startedLeading.Load() { + // Perform cleanup operations here + // For example, releasing resources, closing connections, etc. + klog.Info("Performing cleanup operations...") + } else { + klog.Info("No cleanup needed as we never started leading.") + } os.Exit(0) }, OnNewLeader: func(identity string) { diff --git a/tools/leaderelection/leaderelection.go b/tools/leaderelection/leaderelection.go index 64c49f61..c3c1d9be 100644 --- a/tools/leaderelection/leaderelection.go +++ b/tools/leaderelection/leaderelection.go @@ -173,7 +173,10 @@ type LeaderElectionConfig struct { type LeaderCallbacks struct { // OnStartedLeading is called when a LeaderElector client starts leading OnStartedLeading func(context.Context) - // OnStoppedLeading is called when a LeaderElector client stops leading + // OnStoppedLeading is called when a LeaderElector client stops leading. + // This callback is always called when the LeaderElector exits, even if it did not start leading. + // Users should not assume that OnStoppedLeading is only called after OnStartedLeading. + // see: https://github.com/kubernetes/kubernetes/pull/127675#discussion_r1780059887 OnStoppedLeading func() // OnNewLeader is called when the client observes a leader that is // not the previously observed leader. This includes the first observed