diff --git a/src/KubernetesClient/LeaderElection/LeaderElector.cs b/src/KubernetesClient/LeaderElection/LeaderElector.cs
index d78a967ba..dce925d5a 100644
--- a/src/KubernetesClient/LeaderElection/LeaderElector.cs
+++ b/src/KubernetesClient/LeaderElection/LeaderElector.cs
@@ -49,7 +49,12 @@ public string GetLeader()
return observedRecord?.HolderIdentity;
}
- public async Task RunAsync(CancellationToken cancellationToken = default)
+ ///
+ /// Tries to acquire and hold leadership once via a Kubernetes Lease resource.
+ /// Will complete the returned Task and not retry to acquire leadership again after leadership is lost once.
+ ///
+ /// A token to cancel the operation.
+ public async Task RunUntilLeadershipLostAsync(CancellationToken cancellationToken = default)
{
await AcquireAsync(cancellationToken).ConfigureAwait(false);
@@ -107,6 +112,32 @@ public async Task RunAsync(CancellationToken cancellationToken = default)
}
}
+ ///
+ /// Tries to acquire leadership via a Kubernetes Lease resource.
+ /// Will retry to acquire leadership again after leadership was lost.
+ ///
+ /// A Task which completes only on cancellation
+ /// A token to cancel the operation.
+ public async Task RunAndTryToHoldLeadershipForeverAsync(CancellationToken cancellationToken = default)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ await RunUntilLeadershipLostAsync(cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ ///
+ /// Tries to acquire leadership once via a Kubernetes Lease resource.
+ /// Will complete the returned Task and not retry to acquire leadership again after leadership is lost once.
+ ///
+ ///
+ /// A token to cancel the operation.
+ [Obsolete("Replaced by RunUntilLeadershipLostAsync to encode behavior in method name.")]
+ public Task RunAsync(CancellationToken cancellationToken = default)
+ {
+ return RunUntilLeadershipLostAsync(cancellationToken);
+ }
+
private async Task TryAcquireOrRenew(CancellationToken cancellationToken)
{
var l = config.Lock;
diff --git a/tests/KubernetesClient.Tests/LeaderElection/LeaderElectionTests.cs b/tests/KubernetesClient.Tests/LeaderElection/LeaderElectionTests.cs
index 1e65f8dfb..22cb12412 100644
--- a/tests/KubernetesClient.Tests/LeaderElection/LeaderElectionTests.cs
+++ b/tests/KubernetesClient.Tests/LeaderElection/LeaderElectionTests.cs
@@ -71,7 +71,7 @@ public void SimpleLeaderElection()
countdown.Signal();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
countdown.Wait(TimeSpan.FromSeconds(10));
@@ -164,7 +164,7 @@ public void LeaderElection()
lockAStopLeading.Set();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
@@ -186,7 +186,7 @@ public void LeaderElection()
testLeaderElectionLatch.Signal();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
testLeaderElectionLatch.Wait(TimeSpan.FromSeconds(15));
@@ -272,7 +272,7 @@ public void LeaderElectionWithRenewDeadline()
countdown.Signal();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
countdown.Wait(TimeSpan.FromSeconds(15));
@@ -305,7 +305,7 @@ public void LeaderElectionThrowException()
try
{
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
}
catch (Exception e)
{
@@ -362,7 +362,7 @@ public void LeaderElectionReportLeaderOnStart()
countdown.Signal();
};
- Task.Run(() => leaderElector.RunAsync());
+ Task.Run(() => leaderElector.RunUntilLeadershipLostAsync());
countdown.Wait(TimeSpan.FromSeconds(10));
Assert.True(notifications.SequenceEqual(new[]
@@ -403,7 +403,7 @@ public void LeaderElectionShouldReportLeaderItAcquiresOnStart()
countdown.Signal();
};
- Task.Run(() => leaderElector.RunAsync());
+ Task.Run(() => leaderElector.RunUntilLeadershipLostAsync());
countdown.Wait(TimeSpan.FromSeconds(10));
Assert.True(notifications.SequenceEqual(new[] { "foo1" }));