Пример #1
0
        public void ApplyCommand(BaseCommand command)
        {
            try
            {
                switch (command)
                {
                case UpsertNodeInformation t1:
                    if (Nodes.ContainsKey(t1.Id))
                    {
                        Nodes[t1.Id] = new NodeInformation()
                        {
                            Name             = t1.Name,
                            TransportAddress = t1.TransportAddress,
                            Id            = t1.Id,
                            IsContactable = t1.IsContactable
                        };
                    }
                    else
                    {
                        //Only add if it is marking as contactable
                        if (t1.IsContactable)
                        {
                            var nodes = Nodes.Where(n => n.Value.TransportAddress == t1.TransportAddress);
                            if (nodes.Count() > 0)
                            {
                                foreach (var node in nodes)
                                {
                                    Nodes.Remove(node.Key, out _);
                                }
                            }
                            Nodes.TryAdd(t1.Id, new NodeInformation()
                            {
                                Name             = t1.Name,
                                TransportAddress = t1.TransportAddress,
                                Id            = t1.Id,
                                IsContactable = t1.IsContactable
                            });
                        }
                    }
                    break;

                case DeleteNodeInformation t1:
                    if (Nodes.ContainsKey(t1.Id))
                    {
                        Nodes.TryRemove(t1.Id, out _);
                    }
                    break;

                case CreateIndex t1:
                    Indexes.TryAdd(t1.Type, new Index()
                    {
                        Shards = t1.Shards.Select(s => s.DeepCopy()).ToList(),
                        Type   = t1.Type
                    });
                    break;

                case UpdateClusterTasks t1:
                    if (t1.TasksToAdd != null)
                    {
                        foreach (var task in t1.TasksToAdd)
                        {
                            if (GetRunningTask(task.UniqueRunningId) == null)
                            {
                                if (!ClusterTasks.TryAdd(task.Id, SystemExtension.Clone(task)))
                                {
                                    //Can't add a task twice
                                    if (ClusterTasks.ContainsKey(task.Id))
                                    {
                                        if (_logger == null)
                                        {
                                            Console.WriteLine("Critical error while trying to add cluster task " + task.Id + " the id already exists as the object " + JsonConvert.SerializeObject(ClusterTasks[task.Id], Formatting.Indented));
                                        }
                                        else
                                        {
                                            _logger.LogDebug("Critical error while trying to add cluster task " + task.Id + " the id already exists as the object " + JsonConvert.SerializeObject(ClusterTasks[task.Id], Formatting.Indented));
                                        }
                                    }
                                    else
                                    {
                                        throw new Exception("Critical error while trying to add cluster task " + task.Id);
                                    }
                                }
                            }
                            else
                            {
                                if (_logger == null)
                                {
                                    Console.WriteLine("The task already exists and is running. Skipping addition of task " + task.Id);
                                }
                                else
                                {
                                    _logger.LogInformation("The task already exists and is running. Skipping addition of task " + task.Id);
                                }
                            }
                        }
                    }
                    if (t1.TasksToRemove != null)
                    {
                        foreach (var task in t1.TasksToRemove)
                        {
                            if (!ClusterTasks.TryRemove(task, out _))
                            {
                                throw new Exception("Critical error while trying to remove cluster task " + task);
                            }
                        }
                    }
                    if (t1.TasksToUpdate != null)
                    {
                        foreach (var task in t1.TasksToUpdate)
                        {
                            if (ClusterTasks.ContainsKey(task.TaskId))
                            {
                                ClusterTasks[task.TaskId].CompletedOn  = task.CompletedOn;
                                ClusterTasks[task.TaskId].Status       = task.Status;
                                ClusterTasks[task.TaskId].ErrorMessage = task.ErrorMessage;
                            }
                            else
                            {
                                if (_logger == null)
                                {
                                    Console.WriteLine("Critical error while trying to update cluster task " + task.TaskId + " task is not present in dictionary.");
                                }
                                else
                                {
                                    _logger.LogInformation("Critical error while trying to update cluster task " + task.TaskId + " task is not present in dictionary.");
                                }
                            }
                        }
                    }
                    break;

                case UpdateShardMetadataAllocations t1:
                    if (t1.InsyncAllocationsToAdd != null)
                    {
                        var newList = new HashSet <Guid>();
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().InsyncAllocations.ToList().ForEach(ia => newList.Add(ia));
                        foreach (var allocation in t1.InsyncAllocationsToAdd)
                        {
                            //Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().InsyncAllocations = newList;
                            newList.Add(allocation);
                        }
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().InsyncAllocations = new HashSet <Guid>(newList);
                        // Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().StaleAllocations = Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().StaleAllocations.Where(sa => !t1.InsyncAllocationsToAdd.Contains(sa)).ToHashSet();
                    }
                    if (t1.InsyncAllocationsToRemove != null)
                    {
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().InsyncAllocations = new HashSet <Guid>(Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().InsyncAllocations.Where(ia => !t1.InsyncAllocationsToRemove.Contains(ia)));
                    }
                    if (t1.StaleAllocationsToAdd != null)
                    {
                        var newList = new HashSet <Guid>();
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().StaleAllocations.ToList().ForEach(ia => newList.Add(ia));
                        foreach (var allocation in t1.StaleAllocationsToAdd)
                        {
                            newList.Add(allocation);
                        }
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().StaleAllocations = new HashSet <Guid>(newList);
                    }
                    if (t1.StaleAllocationsToRemove != null)
                    {
                        var newList = new HashSet <Guid>();
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().StaleAllocations.Where(sa => !t1.StaleAllocationsToRemove.Contains(sa)).ToList().ForEach(ia => newList.Add(ia));
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().StaleAllocations = new HashSet <Guid>(newList);
                    }

                    if (t1.PrimaryAllocation != null)
                    {
                        Indexes[t1.Type].Shards.Where(s => s.Id == t1.ShardId).FirstOrDefault().PrimaryAllocation = t1.PrimaryAllocation.Value;
                    }
                    break;

                case SetLock t1:
                    var stringLockResult = Locks.TryAdd(t1.Name, new Lock()
                    {
                        LockTimeoutMs = t1.TimeoutMs,
                        Name          = t1.Name,
                        LockId        = t1.LockId,
                        CreatedOn     = t1.CreatedOn
                    });
                    if (!stringLockResult)
                    {
                        throw new ConflictingObjectLockException("String " + t1.Name + " is already locked.");
                    }
                    break;

                case RemoveLock t1:
                    string lockName = t1.Name;
                    var    objectLocksWithLockId = Locks.Where(ob => ob.Value.LockId == t1.LockId).Select(t => t.Value);
                    if (objectLocksWithLockId.Count() == 0)
                    {
                        throw new ConflictingObjectLockException("No lock with id " + t1.LockId);
                    }

                    Lock existingStringLock;
                    var  removeStringLockResult = Locks.TryRemove(t1.Name, out existingStringLock);
                    if (!removeStringLockResult)
                    {
                        throw new ConflictingObjectLockException("String Lock " + t1.Name + " did not exist in locks.");
                    }
                    break;

                default:
                    ApplyCommandToState(command);
                    break;
                }
            }
            catch (Exception e)
            {
                throw new Exception("Failed to apply command " + command.CommandName + " to state with exception \"" + e.Message + "\"." + Environment.NewLine + JsonConvert.SerializeObject(command, Formatting.Indented));
            }
        }
Пример #2
0
 public abstract void ApplyCommandToState(BaseCommand command);