diff --git a/src/KubernetesClient/LeaderElection/LeaderElector.cs b/src/KubernetesClient/LeaderElection/LeaderElector.cs
index d78a967..dce925d 100644
--- a/src/KubernetesClient/LeaderElection/LeaderElector.cs
+++ b/src/KubernetesClient/LeaderElection/LeaderElector.cs
@@ -49,7 +49,12 @@ namespace k8s.LeaderElection
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 @@ namespace k8s.LeaderElection
}
}
+ ///
+ /// 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 1e65f8d..22cb124 100644
--- a/tests/KubernetesClient.Tests/LeaderElection/LeaderElectionTests.cs
+++ b/tests/KubernetesClient.Tests/LeaderElection/LeaderElectionTests.cs
@@ -71,7 +71,7 @@ namespace k8s.Tests.LeaderElection
countdown.Signal();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
countdown.Wait(TimeSpan.FromSeconds(10));
@@ -164,7 +164,7 @@ namespace k8s.Tests.LeaderElection
lockAStopLeading.Set();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
@@ -186,7 +186,7 @@ namespace k8s.Tests.LeaderElection
testLeaderElectionLatch.Signal();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
testLeaderElectionLatch.Wait(TimeSpan.FromSeconds(15));
@@ -272,7 +272,7 @@ namespace k8s.Tests.LeaderElection
countdown.Signal();
};
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
});
countdown.Wait(TimeSpan.FromSeconds(15));
@@ -305,7 +305,7 @@ namespace k8s.Tests.LeaderElection
try
{
- leaderElector.RunAsync().Wait();
+ leaderElector.RunUntilLeadershipLostAsync().Wait();
}
catch (Exception e)
{
@@ -362,7 +362,7 @@ namespace k8s.Tests.LeaderElection
countdown.Signal();
};
- Task.Run(() => leaderElector.RunAsync());
+ Task.Run(() => leaderElector.RunUntilLeadershipLostAsync());
countdown.Wait(TimeSpan.FromSeconds(10));
Assert.True(notifications.SequenceEqual(new[]
@@ -403,7 +403,7 @@ namespace k8s.Tests.LeaderElection
countdown.Signal();
};
- Task.Run(() => leaderElector.RunAsync());
+ Task.Run(() => leaderElector.RunUntilLeadershipLostAsync());
countdown.Wait(TimeSpan.FromSeconds(10));
Assert.True(notifications.SequenceEqual(new[] { "foo1" }));