public void ClientAdded(PersistentSubscriptionClient client) { lock (_stateLock) { var newNode = new Node(client); _state.AddNode(newNode); client.EventConfirmed += OnEventRemoved; } }
public void AddNode(Node newNode) { Nodes.Add(newNode); TotalCapacity += newNode.MaximumInFlightMessages; var clientCount = Nodes.Count(_ => _.State == Node.NodeState.Connected); var maxBalancedClientAssignmentCount = (int)Math.Ceiling(AssignmentCount / (decimal)clientCount); var reassignments = new List<uint>(); foreach (var existingClient in Nodes) { if (existingClient == newNode || existingClient.State == Node.NodeState.Disconnected) { continue; } if (existingClient.AssignmentCount > maxBalancedClientAssignmentCount) { var assignmentsToMove = Assignments .Select((node, bucket) => Tuple.Create(node, bucket)) .Where(_ => _.Item1.NodeId == existingClient.NodeId && _.Item1.State == BucketAssignment.BucketState.Assigned) .OrderBy(_ => _.Item1.InFlightCount) // Take buckets without inflight messages first. .Take(existingClient.AssignmentCount - maxBalancedClientAssignmentCount); foreach (var assignment in assignmentsToMove) { reassignments.Add((uint)assignment.Item2); } } } foreach (var reassignment in reassignments) { ApplyBucketAssigned(reassignment, newNode.NodeId); } Clean(); }