private async Task <bool> TryAcquireOrRenew(CancellationToken cancellationToken) { var l = config.Lock; var leaderElectionRecord = new LeaderElectionRecord() { HolderIdentity = l.Identity, LeaseDurationSeconds = config.LeaseDuration.Seconds, AcquireTime = DateTime.UtcNow, RenewTime = DateTime.UtcNow, LeaderTransitions = 0, }; // 1. obtain or create the ElectionRecord LeaderElectionRecord oldLeaderElectionRecord = null; try { oldLeaderElectionRecord = await l.GetAsync(cancellationToken).ConfigureAwait(false); } catch (HttpOperationException e) { if (e.Response.StatusCode != HttpStatusCode.NotFound) { return(false); } } if (oldLeaderElectionRecord?.AcquireTime == null || oldLeaderElectionRecord?.RenewTime == null || oldLeaderElectionRecord?.HolderIdentity == null) { var created = await l.CreateAsync(leaderElectionRecord, cancellationToken).ConfigureAwait(false); if (created) { observedRecord = leaderElectionRecord; observedTime = DateTimeOffset.Now; return(true); } return(false); } // 2. Record obtained, check the Identity & Time if (!Equals(observedRecord, oldLeaderElectionRecord)) { observedRecord = oldLeaderElectionRecord; observedTime = DateTimeOffset.Now; } if (!string.IsNullOrEmpty(oldLeaderElectionRecord.HolderIdentity) && observedTime + config.LeaseDuration > DateTimeOffset.Now && !IsLeader()) { // lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity return(false); } // 3. We're going to try to update. The leaderElectionRecord is set to it's default // here. Let's correct it before updating. if (IsLeader()) { leaderElectionRecord.AcquireTime = oldLeaderElectionRecord.AcquireTime; leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions; } else { leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions + 1; } var updated = await l.UpdateAsync(leaderElectionRecord, cancellationToken).ConfigureAwait(false); if (!updated) { return(false); } observedRecord = leaderElectionRecord; observedTime = DateTimeOffset.Now; return(true); }
protected bool Equals(LeaderElectionRecord other) { return(HolderIdentity == other?.HolderIdentity && Nullable.Equals(AcquireTime, other.AcquireTime) && Nullable.Equals(RenewTime, other.RenewTime)); }