Skip to content

Commit

Permalink
fix fabric8io#4547: preventing a cancelled leader elector
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed Oct 31, 2022
1 parent 68a295d commit ed48daa
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,7 @@
### 6.3-SNAPSHOT

#### Bugs
Fix #4547: preventing timing issues with leader election cancel

#### Improvements

Expand Down
Expand Up @@ -50,6 +50,7 @@ public class LeaderElector {
private final AtomicReference<LeaderElectionRecord> observedRecord = new AtomicReference<>();
private final AtomicReference<LocalDateTime> observedTime = new AtomicReference<>();
private final Executor executor;
private boolean stopped;

public LeaderElector(KubernetesClient kubernetesClient, LeaderElectionConfig leaderElectionConfig, Executor executor) {
this.kubernetesClient = kubernetesClient;
Expand Down Expand Up @@ -110,7 +111,8 @@ public CompletableFuture<?> start() {
return result;
}

private void stopLeading() {
synchronized private void stopLeading() {
stopped = true;
LeaderElectionRecord current = observedRecord.get();
if (current == null || !isLeader(current)) {
return; // not leading
Expand Down Expand Up @@ -182,7 +184,10 @@ private CompletableFuture<Void> renewWithTimeout() {
}, () -> leaderElectionConfig.getRetryPeriod().toMillis(), executor);
}

boolean tryAcquireOrRenew() throws LockException {
synchronized boolean tryAcquireOrRenew() throws LockException {
if (stopped) {
return false;
}
final Lock lock = leaderElectionConfig.getLock();
final ZonedDateTime now = now();
final LeaderElectionRecord oldLeaderElectionRecord = lock.get(kubernetesClient);
Expand Down
Expand Up @@ -134,6 +134,8 @@ void shouldReleaseWhenCanceled() throws Exception {
Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> Utils.isNullOrEmpty(activeLer.get().getHolderIdentity()));
assertEquals(0, activeLer.get().getLeaderTransitions());

// create a new elector, they are no good after a single use
leaderElector = new LeaderElector(mock(NamespacedKubernetesClient.class), lec, CommonThreadPool.get());
// the leader is now empty/null, we should be able to re-acquire
assertTrue(leaderElector.tryAcquireOrRenew());

Expand Down

0 comments on commit ed48daa

Please sign in to comment.