Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
 protected bool Equals(LeaderElectionRecord other)
 {
     return(HolderIdentity == other?.HolderIdentity && Nullable.Equals(AcquireTime, other.AcquireTime) && Nullable.Equals(RenewTime, other.RenewTime));
 }