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); } }
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}"); } } }