public void LeastShardAllocationStrategy_should_allocate_to_region_with_least_number_of_shards() { var allocations = new Dictionary <IActorRef, IImmutableList <string> > { { _regionA, new [] { "shard1" }.ToImmutableList() }, { _regionB, new [] { "shard2" }.ToImmutableList() }, { _regionC, ImmutableList <string> .Empty } }.ToImmutableDictionary(); var result = _allocationStrategy.AllocateShard(_regionA, "shard3", allocations).Result; Assert.Equal(result, _regionC); }
private void HandleGetShardHome(GetShardHome getShardHome) { var shard = getShardHome.Shard; if (_rebalanceInProgress.Contains(shard)) { Log.Debug("GetShardHome [{0}] request ignored, because rebalance is in progress for this shard.", shard); } else if (!HasAllRegionsRegistered()) { Log.Debug("GetShardHome [{0}] request ignored, because not all regions have registered yet.", shard); } else { if (_currentState.Shards.TryGetValue(shard, out var region)) { if (_regionTerminationInProgress.Contains(region)) { Log.Debug("GetShardHome [{0}] request ignored, due to region [{1}] termination in progress.", shard, region); } else { Sender.Tell(new ShardHome(shard, region)); } } else { var activeRegions = _currentState.Regions.RemoveRange(_gracefullShutdownInProgress); if (activeRegions.Count != 0) { var getShardHomeSender = Sender; var regionTask = AllocationStrategy.AllocateShard(getShardHomeSender, shard, activeRegions); // if task completed immediately, just continue if (regionTask.IsCompleted && !regionTask.IsFaulted) { ContinueGetShardHome(shard, regionTask.Result, getShardHomeSender); } else { regionTask.ContinueWith(t => !(t.IsFaulted || t.IsCanceled) ? new AllocateShardResult(shard, t.Result, getShardHomeSender) : new AllocateShardResult(shard, null, getShardHomeSender), TaskContinuationOptions.ExecuteSynchronously) .PipeTo(Self); } } } } }
internal static IImmutableDictionary <IActorRef, IImmutableList <string> > AfterRebalance( IShardAllocationStrategy allocationStrategy, IImmutableDictionary <IActorRef, IImmutableList <string> > allocations, IImmutableSet <string> rebalance) { var allocationsAfterRemoval = allocations.SetItems(allocations.Select(i => new KeyValuePair <IActorRef, IImmutableList <string> >(i.Key, i.Value.ToImmutableHashSet().Except(rebalance).OrderBy(j => j).ToImmutableList()))); IImmutableDictionary <IActorRef, IImmutableList <string> > acc = allocationsAfterRemoval; foreach (var shard in rebalance.OrderBy(i => i)) { var region = allocationStrategy.AllocateShard(new DummyActorRef(), shard, acc).Result; acc = acc.SetItem(region, acc[region].Add(shard)); } return(acc); }