Example #1
0
        public async Task ExecuteCoordinatorRoleAsync(Guid coordinatorClientId,
                                                      ClientEvent clientEvent,
                                                      OnChangeActions onChangeActions,
                                                      CancellationToken token)
        {
            currentFencingToken = clientEvent.FencingToken;
            Client self = await clientService.KeepAliveAsync(coordinatorClientId);

            List <string> resourcesNow = (await resourceService.GetResourcesAsync(clientEvent.ResourceGroup))
                                         .OrderBy(x => x)
                                         .ToList();
            List <Client> clientsNow = await GetLiveClientsAsync(clientEvent, coordinatorClientId);

            List <Guid> clientIds = clientsNow.Select(x => x.ClientId).ToList();

            clientIds.Add(coordinatorClientId);

            if (clientsNow.Any(x => x.FencingToken > clientEvent.FencingToken))
            {
                clientEvent.CoordinatorToken.FencingTokenViolation = true;
                return;
            }

            if (self.ClientStatus == ClientStatus.Terminated || stoppedDueToInternalErrorFlag)
            {
                stoppedDueToInternalErrorFlag = false;
                await clientService.SetClientStatusAsync(coordinatorClientId, ClientStatus.Waiting);

                logger.Debug(coordinatorClientId.ToString(),
                             "Status change: COORDINATOR was terminated due to an error");
                await TriggerRebalancingAsync(coordinatorClientId, clientEvent, clientsNow, resourcesNow,
                                              onChangeActions,
                                              token);
            }
            else if (!resources.OrderBy(x => x).SequenceEqual(resourcesNow.OrderBy(x => x)))
            {
                logger.Debug(coordinatorClientId.ToString(),
                             $"Resource change: Old: {string.Join(",", resources.OrderBy(x => x))} New: {string.Join(",", resourcesNow.OrderBy(x => x))}");
                await TriggerRebalancingAsync(coordinatorClientId, clientEvent, clientsNow, resourcesNow,
                                              onChangeActions,
                                              token);
            }
            else if (!clients.OrderBy(x => x).SequenceEqual(clientIds.OrderBy(x => x)))
            {
                logger.Debug(coordinatorClientId.ToString(),
                             $"Client change: Old: {string.Join(",", clients.OrderBy(x => x))} New: {string.Join(",", clientIds.OrderBy(x => x))}");
                await TriggerRebalancingAsync(coordinatorClientId, clientEvent, clientsNow, resourcesNow,
                                              onChangeActions,
                                              token);
            }
        }
Example #2
0
        public async Task ExecuteFollowerRoleAsync(Guid followerClientId,
                                                   ClientEvent clientEvent,
                                                   OnChangeActions onChangeActions,
                                                   CancellationToken token)
        {
            Client self = await clientService.KeepAliveAsync(followerClientId);

            logger.Debug(followerClientId.ToString(),
                         $"FOLLOWER : Keep Alive sent. Coordinator: {self.CoordinatorStatus} Client: {self.ClientStatus}");
            if (self.CoordinatorStatus == CoordinatorStatus.StopActivity)
            {
                if (self.ClientStatus == ClientStatus.Active)
                {
                    logger.Info(followerClientId.ToString(), "-------------- Stopping activity ---------------");
                    logger.Debug(followerClientId.ToString(), "FOLLOWER : Invoking on stop actions");
                    foreach (Action stopAction in onChangeActions.OnStopActions)
                    {
                        stopAction.Invoke();
                    }

                    store.SetResources(new SetResourcesRequest
                    {
                        AssignmentStatus = AssignmentStatus.AssignmentInProgress, Resources = new List <string>()
                    });
                    await clientService.SetClientStatusAsync(followerClientId, ClientStatus.Waiting);

                    logger.Info(followerClientId.ToString(), $"FOLLOWER : State= {self.ClientStatus} -> WAITING");
                }
                else
                {
                    logger.Debug(followerClientId.ToString(), $"FOLLOWER : State= {self.ClientStatus}");
                }
            }
            else if (self.CoordinatorStatus == CoordinatorStatus.ResourcesGranted)
            {
                if (self.ClientStatus == ClientStatus.Waiting)
                {
                    if (self.AssignedResources.Any())
                    {
                        store.SetResources(new SetResourcesRequest
                        {
                            AssignmentStatus = AssignmentStatus.ResourcesAssigned,
                            Resources        = self.AssignedResources
                        });
                    }
                    else
                    {
                        store.SetResources(new SetResourcesRequest
                        {
                            AssignmentStatus = AssignmentStatus.NoResourcesAssigned, Resources = new List <string>()
                        });
                    }

                    if (token.IsCancellationRequested)
                    {
                        return;
                    }

                    await clientService.SetClientStatusAsync(followerClientId, ClientStatus.Active);

                    if (self.AssignedResources.Any())
                    {
                        logger.Info(followerClientId.ToString(),
                                    $"FOLLOWER : Granted resources={string.Join(",", self.AssignedResources)}");
                    }
                    else
                    {
                        logger.Info(followerClientId.ToString(), "FOLLOWER : No resources available to be assigned.");
                    }

                    foreach (Action <IList <string> > startAction in onChangeActions.OnStartActions)
                    {
                        startAction.Invoke(self.AssignedResources.Any() ? self.AssignedResources : new List <string>());
                    }

                    logger.Info(followerClientId.ToString(), $"FOLLOWER : State={self.ClientStatus} -> ACTIVE");
                    logger.Info(followerClientId.ToString(), "-------------- Activity started ---------------");
                }
                else
                {
                    logger.Debug(followerClientId.ToString(), $"FOLLOWER : State= {self.ClientStatus}");
                }
            }
        }