public async Task <BecomeCoordinatorResult> BecomeCoordinatorAsync(int currentEpoch)
        {
            try
            {
                this.ignoreWatches = false;
                await this.zooKeeperService.IncrementAndWatchEpochAsync(currentEpoch, this);

                await this.zooKeeperService.WatchNodesAsync(this);

                var getResourcesRes = await this.zooKeeperService.GetResourcesAsync(this, null);

                this.resourcesVersion = getResourcesRes.Version;

                this.status = await this.zooKeeperService.GetStatusAsync();
            }
            catch (ZkStaleVersionException e)
            {
                this.logger.Error(this.clientId, "Could not become coordinator as a stale version number was used", e);
                return(BecomeCoordinatorResult.StaleEpoch);
            }
            catch (ZkInvalidOperationException e)
            {
                this.logger.Error(this.clientId, "Could not become coordinator as an invalid ZooKeeper operation occurred", e);
                return(BecomeCoordinatorResult.Error);
            }

            this.events.Add(CoordinatorEvent.RebalancingTriggered);
            return(BecomeCoordinatorResult.Ok);
        }
Example #2
0
        private async Task SendTriggerRebalancingEvent()
        {
            try
            {
                StatusZnode status = await zooKeeperService.WatchStatusAsync(this);

                statusVersion = status.Version;
                events.Add(FollowerEvent.RebalancingTriggered);
            }
            catch (Exception e)
            {
                logger.Error("Follower - Could not put a watch on the status node", e);
                events.Add(FollowerEvent.PotentialInconsistentState);
            }
        }
Example #3
0
        private async Task <RebalancingResult> ProcessStatusChangeAsync(CancellationToken rebalancingToken)
        {
            StatusZnode status = await zooKeeperService.WatchStatusAsync(this);

            if (status.Version != statusVersion)
            {
                logger.Warn(clientId, "Follower - The status has changed between the notification and response");
            }

            if (rebalancingToken.IsCancellationRequested)
            {
                return(RebalancingResult.Cancelled);
            }

            if (status.RebalancingStatus == RebalancingStatus.StopActivity)
            {
                logger.Info(clientId, "Follower - Status change received - stop activity");
                await store.InvokeOnStopActionsAsync(clientId, "Follower");

                if (rebalancingToken.IsCancellationRequested)
                {
                    return(RebalancingResult.Cancelled);
                }

                await zooKeeperService.SetFollowerAsStopped(clientId);

                logger.Info(clientId, "Follower - Created follower stopped node");
            }
            else if (status.RebalancingStatus == RebalancingStatus.ResourcesGranted)
            {
                logger.Info(clientId, "Follower - Status change received - resources granted");
                ResourcesZnode resources = await zooKeeperService.GetResourcesAsync(null, null);

                List <string> assignedResources = resources.ResourceAssignments.Assignments
                                                  .Where(x => x.ClientId.Equals(clientId))
                                                  .Select(x => x.Resource)
                                                  .ToList();

                logger.Info(clientId, $"Follower - {assignedResources.Count} resources granted");

                if (store.IsInStartedState())
                {
                    logger.Warn(clientId,
                                "Follower - The resources granted status change has been received while already in the started state. Stopped all activity first");
                    await store.InvokeOnStopActionsAsync(clientId, "Follower");
                }

                if (onStartDelay.Ticks > 0)
                {
                    logger.Info(clientId, $"Follower - Delaying on start for {(int)onStartDelay.TotalMilliseconds}ms");
                    await WaitFor(onStartDelay, rebalancingToken);
                }

                if (rebalancingToken.IsCancellationRequested)
                {
                    return(RebalancingResult.Cancelled);
                }

                await store.InvokeOnStartActionsAsync(clientId, "Follower", assignedResources, rebalancingToken,
                                                      followerToken);

                if (rebalancingToken.IsCancellationRequested)
                {
                    return(RebalancingResult.Cancelled);
                }

                await zooKeeperService.SetFollowerAsStarted(clientId);

                logger.Info(clientId, "Follower - Removed follower stopped node");
            }
            else if (status.RebalancingStatus == RebalancingStatus.StartConfirmed)
            {
                logger.Info(clientId, "Follower - All followers confirm started"); // no longer used
            }
            else
            {
                logger.Error(clientId, "Follower - Non-supported status received - ignoring");
            }

            return(RebalancingResult.Complete);
        }