private async Task WaitFor(TimeSpan delayPeriod, CancellationToken token, CoordinatorToken coordinatorToken) { var sw = new Stopwatch(); sw.Start(); while (!token.IsCancellationRequested && !coordinatorToken.FencingTokenViolation) { if (sw.Elapsed < delayPeriod) { await Task.Delay(100); } else { break; } } }
private void PostLeaderEvent(int fencingToken, TimeSpan keepAliveExpiryPeriod, CoordinatorToken coordinatorToken, BlockingCollection <ClientEvent> clientEvents) { this.logger.Debug($"{clientId} is leader"); this.isCoordinator = true; var clientEvent = new ClientEvent() { ResourceGroup = this.resourceGroup, EventType = EventType.Coordinator, FencingToken = fencingToken, CoordinatorToken = coordinatorToken, KeepAliveExpiryPeriod = keepAliveExpiryPeriod }; clientEvents.Add(clientEvent); }
private async Task ExecuteLeaseRenewals(CancellationToken token, BlockingCollection <ClientEvent> clientEvents, Lease lease) { var coordinatorToken = new CoordinatorToken(); PostLeaderEvent(lease.FencingToken, lease.ExpiryPeriod, coordinatorToken, clientEvents); await WaitFor(GetInterval(lease.HeartbeatPeriod), token, coordinatorToken); // lease renewal loop while (!token.IsCancellationRequested && !coordinatorToken.FencingTokenViolation) { var response = await TryRenewLeaseAsync(new RenewLeaseRequest() { ClientId = this.clientId, ResourceGroup = this.resourceGroup, FencingToken = lease.FencingToken }, token); if (response.Result == LeaseResult.Granted) { PostLeaderEvent(lease.FencingToken, lease.ExpiryPeriod, coordinatorToken, clientEvents); await WaitFor(GetInterval(lease.HeartbeatPeriod), token, coordinatorToken); } else if (response.Result == LeaseResult.Denied) { PostFollowerEvent(lease.ExpiryPeriod, clientEvents); await WaitFor(GetInterval(lease.HeartbeatPeriod), token); break; } else if (response.Result == LeaseResult.NoLease) { throw new RebalanserException($"The resource group {this.resourceGroup} does not exist."); } else if (response.IsErrorResponse()) { throw new RebalanserException("An non-recoverable error occurred.", response.Exception); } else { throw new RebalanserException("A non-supported lease result was received"); // should never happen, just in case I screw up in the future } } }