public ReadyEventArgs(ShardId shardId, ICurrentUser currentUser, IReadOnlyList <Snowflake> guildIds) { if (currentUser == null) { throw new ArgumentNullException(nameof(currentUser)); } if (guildIds == null) { throw new ArgumentNullException(nameof(guildIds)); } ShardId = shardId; CurrentUser = currentUser; GuildIds = guildIds; }
/// <summary> /// Attempts to extract <see cref="ShardId"/> from the entity identifier. This /// will only work if the shard identifier has been encoded into the entity /// identifier by an <see cref="IShardEncodingIdentifierGenerator"/>. /// </summary> /// <param name="shardedSessionFactory">The sharded session factory to use to retrieve entity metadata.</param> /// <param name="key">The entity key.</param> /// <param name="result">Returns the extracted <see cref="ShardId"/> if this operation succeeds.</param> /// <returns>Returns <c>true</c> if this operation succeeds or false otherwise.</returns> public static bool TryExtractShardIdFromKey( this IShardedSessionFactoryImplementor shardedSessionFactory, ShardedEntityKey key, out ShardId result) { var sessionFactory = shardedSessionFactory.ControlFactory; var entityPersister = sessionFactory.GetEntityPersister(key.EntityName); var rootEntityName = entityPersister.RootEntityName; var idGenerator = sessionFactory.GetIdentifierGenerator(rootEntityName) as IShardEncodingIdentifierGenerator; if (idGenerator != null) { result = idGenerator.ExtractShardId(key.Id); return true; } result = null; return false; }
/// <summary> /// TBD /// </summary> /// <param name="typeName">TBD</param> /// <param name="shardId">TBD</param> /// <param name="entityProps">TBD</param> /// <param name="settings">TBD</param> /// <param name="extractEntityId">TBD</param> /// <param name="extractShardId">TBD</param> /// <param name="handOffStopMessage">TBD</param> protected Shard( string typeName, string shardId, Props entityProps, ClusterShardingSettings settings, IdExtractor extractEntityId, ShardResolver extractShardId, object handOffStopMessage) { TypeName = typeName; ShardId = shardId; EntityProps = entityProps; Settings = settings; ExtractEntityId = extractEntityId; ExtractShardId = extractShardId; HandOffStopMessage = handOffStopMessage; }
private void DeliverBufferedMessage(ShardId shardId, IActorRef receiver) { if (ShardBuffers.TryGetValue(shardId, out var buffer)) { Log.Debug("Deliver [{0}] buffered messages for shard [{1}]", buffer.Count, shardId); foreach (var m in buffer) { receiver.Tell(m.Key, m.Value); } ShardBuffers = ShardBuffers.Remove(shardId); } _loggedFullBufferWarning = false; _retryCount = 0; }
/// <summary> /// Start a RebalanceWorker to manage the shard rebalance. /// Does nothing if the shard is already in the process of being rebalanced. /// </summary> /// <typeparam name="TCoordinator">TBD</typeparam> /// <param name="coordinator">TBD</param> /// <param name="shard">TBD</param> /// <param name="from">TBD</param> /// <param name="isRebalance">TBD</param> private static void StartShardRebalanceIfNeeded <TCoordinator>( this TCoordinator coordinator, ShardId shard, IActorRef from, bool isRebalance) where TCoordinator : IShardCoordinator { if (!coordinator.RebalanceInProgress.ContainsKey(shard)) { coordinator.RebalanceInProgress = coordinator.RebalanceInProgress.SetItem(shard, ImmutableHashSet <IActorRef> .Empty); var regions = coordinator.CurrentState.Regions.Keys.Union(coordinator.CurrentState.RegionProxies); coordinator.RebalanceWorkers = coordinator.RebalanceWorkers.Add(coordinator.Context.ActorOf( RebalanceWorker.Props(shard, from, coordinator.Settings.TuningParameters.HandOffTimeout, regions, isRebalance) .WithDispatcher(coordinator.Context.Props.Dispatcher))); } }
MongoDatabase GetDatabase(ShardId shardId) { MongoDatabase database = databases.TryGetValue(shardId); if (database == null) { lock (syscRoot) { database = databases.TryGetValue(shardId); if (database == null) { database = OpenDatabase(shardId); databases.Add(shardId, database); } } } return(database); }
private void BufferMessage(ShardId shardId, Msg message, IActorRef sender) { var totalBufferSize = TotalBufferSize; if (totalBufferSize >= Settings.TunningParameters.BufferSize) { if (_loggedFullBufferWarning) { Log.Debug("Buffer is full, dropping message for shard [{0}]", shardId); } else { Log.Warning("Buffer is full, dropping message for shard [{0}]", shardId); _loggedFullBufferWarning = true; } Context.System.DeadLetters.Tell(message); } else { IImmutableList <KeyValuePair <Msg, IActorRef> > buffer; if (!ShardBuffers.TryGetValue(shardId, out buffer)) { buffer = ImmutableList <KeyValuePair <Msg, IActorRef> > .Empty; } ShardBuffers = ShardBuffers.SetItem(shardId, buffer.Add(new KeyValuePair <object, IActorRef>(message, sender))); // log some insight to how buffers are filled up every 10% of the buffer capacity var total = totalBufferSize + 1; var bufferSize = Settings.TunningParameters.BufferSize; if (total % (bufferSize / 10) == 0) { var logMsg = "ShardRegion for [{0}] is using [{1}] of it's buffer capacity"; if ((total > bufferSize / 2)) { Log.Warning(logMsg + " The coordinator might not be available. You might want to check cluster membership status.", TypeName, 100 * total / bufferSize); } else { Log.Warning(logMsg, TypeName, 100 * total / bufferSize); } } } }
MongoDatabase OpenDatabase(ShardId shardId) { var shardNodes = ToolSection.Instance.TryGetNodes("shard/shardIds/shardId"); var shardNode = shardNodes.FirstOrDefault(o => o.Attributes.TryGetValue("id") == shardId.Id); if (shardNode == null) { throw new MissConfigurationException(ToolSection.Instance.RootNode, "shard/shardIds/shardId"); } var connectionName = shardNode.Attributes.TryGetValue("connectionName"); if (String.IsNullOrEmpty(connectionName)) { throw new ArgumentNullException("必须为分区 " + shardId.Id + " 指定数据源链接的名称路径 shard/shardIds/shardId/connectionName "); } return(MongoDatabase.Create(ConfigurationManager.ConnectionStrings[connectionName].ConnectionString)); }
/// <inheritdoc/> public void Reset(ShardId shardId = default) { lock (this) { if (shardId.Count <= 1) { _caches.Clear(); foreach (var type in _supportedTypes) { var cacheType = typeof(SynchronizedDictionary <,>).MakeGenericType(typeof(Snowflake), type); var cache = Activator.CreateInstance(cacheType); _caches.Add(type, cache); } _nestedCaches.Clear(); foreach (var type in _supportedNestedTypes) { var cache = new SynchronizedDictionary <Snowflake, object>(); _nestedCaches.Add(type, cache); } } else { if (_caches.GetValueOrDefault(typeof(CachedGuild)) is ISynchronizedDictionary <Snowflake, CachedGuild> guildsCache) { lock (guildsCache) { foreach (var guildId in guildsCache.Keys) { if (ShardId.ForGuildId(guildId, shardId.Count) != shardId) { continue; } guildsCache.Remove(guildId); InternalReset(guildId); } } } } } }
public void TestSelectShardForNewObject() { IList<ShardId> shardIds = new List<ShardId>(); ShardId shardId = new ShardId(1); IShardLoadBalancer balancer = Mock<IShardLoadBalancer>(); using (Mocks.Record()) { Expect.Call(balancer.NextShardId).Return(shardId); Expect.Call(balancer.NextShardId).Return(shardId); } using (Mocks.Playback()) { LoadBalancedShardSelectionStrategy strategy = new LoadBalancedShardSelectionStrategy(balancer); Assert.AreEqual(shardId, strategy.SelectShardIdForNewObject(null)); Assert.AreEqual(shardId, strategy.SelectShardIdForNewObject(null)); } }
public void TestSelectShardForNewObject() { IList <ShardId> shardIds = new List <ShardId>(); ShardId shardId = new ShardId(1); IShardLoadBalancer balancer = Mock <IShardLoadBalancer>(); using (Mocks.Record()) { Expect.Call(balancer.NextShardId).Return(shardId); Expect.Call(balancer.NextShardId).Return(shardId); } using (Mocks.Playback()) { LoadBalancedShardSelectionStrategy strategy = new LoadBalancedShardSelectionStrategy(balancer); Assert.AreEqual(shardId, strategy.SelectShardIdForNewObject(null)); Assert.AreEqual(shardId, strategy.SelectShardIdForNewObject(null)); } }
public static Props Props( string typeName, ShardId shardId, Props entityProps, ClusterShardingSettings settings, ExtractEntityId extractEntityId, ExtractShardId extractShardId, object handOffStopMessage) { if (settings.RememberEntities) { return(Actor.Props.Create(() => new PersistentShardActor(typeName, shardId, entityProps, settings, extractEntityId, extractShardId, handOffStopMessage)) .WithDeploy(Deploy.Local)); } else { return(Actor.Props.Create(() => new ShardActor(typeName, shardId, entityProps, settings, extractEntityId, extractShardId, handOffStopMessage)) .WithDeploy(Deploy.Local)); } }
public HandOffStopper(ShardId shard, IActorRef replyTo, IEnumerable <IActorRef> entities, object stopMessage) { var remaining = new HashSet <IActorRef>(entities); Receive <Terminated>(t => { remaining.Remove(t.ActorRef); if (remaining.Count == 0) { replyTo.Tell(new PersistentShardCoordinator.ShardStopped(shard)); Context.Stop(Self); } }); foreach (var aref in remaining) { Context.Watch(aref); aref.Tell(stopMessage); } }
ISessionFactory GetSessionFactory(ShardId shardId) { ISessionFactory factory = sessionFactories.TryGetValue(shardId); if (factory == null) { lock (syscRoot) { factory = sessionFactories.TryGetValue(shardId); if (factory == null) { using (var scope = ProfilerContext.Profile("create session factory")) { factory = CreateSessionFactory(shardId); } sessionFactories.Add(shardId, factory); } } } return(factory); }
private IActorRef GetShard(ShardId id) { if (StartingShards.Contains(id)) { return(ActorRefs.Nobody); } //TODO: change on ConcurrentDictionary.GetOrAdd? if (!Shards.TryGetValue(id, out var region)) { if (EntityProps == null) { throw new IllegalStateException("Shard must not be allocated to a proxy only ShardRegion"); } if (ShardsByRef.Values.All(shardId => shardId != id)) { Log.Debug("Starting shard [{0}] in region", id); var name = Uri.EscapeDataString(id); var shardRef = Context.Watch(Context.ActorOf(Sharding.Shards.Props( TypeName, id, EntityProps, Settings, ExtractEntityId, ExtractShardId, HandOffStopMessage, _replicator, _majorityMinCap).WithDispatcher(Context.Props.Dispatcher), name)); ShardsByRef = ShardsByRef.SetItem(shardRef, id); Shards = Shards.SetItem(id, shardRef); StartingShards = StartingShards.Add(id); return(shardRef); } } return(region ?? ActorRefs.Nobody); }
public DDataShard( string typeName, ShardId shardId, Func <string, Props> entityProps, ClusterShardingSettings settings, ExtractEntityId extractEntityId, ExtractShardId extractShardId, object handOffStopMessage, IActorRef replicator, int majorityCap) { TypeName = typeName; ShardId = shardId; EntityProps = entityProps; Settings = settings; ExtractEntityId = extractEntityId; ExtractShardId = extractShardId; HandOffStopMessage = handOffStopMessage; Replicator = replicator; MajorityCap = majorityCap; RememberedEntitiesRecoveryStrategy = Settings.TunningParameters.EntityRecoveryStrategy == "constant" ? EntityRecoveryStrategy.ConstantStrategy( Context.System, Settings.TunningParameters.EntityRecoveryConstantRateStrategyFrequency, Settings.TunningParameters.EntityRecoveryConstantRateStrategyNumberOfEntities) : EntityRecoveryStrategy.AllStrategy; var idleInterval = TimeSpan.FromTicks(Settings.PassivateIdleEntityAfter.Ticks / 2); PassivateIdleTask = Settings.ShouldPassivateIdleEntities ? Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(idleInterval, idleInterval, Self, Shard.PassivateIdleTick.Instance, Self) : null; _readConsistency = new ReadMajority(settings.TunningParameters.WaitingForStateTimeout, majorityCap); _writeConsistency = new WriteMajority(settings.TunningParameters.UpdatingStateTimeout, majorityCap); _stateKeys = Enumerable.Range(0, NrOfKeys).Select(i => new ORSetKey <EntryId>($"shard-{typeName}-{shardId}-{i}")).ToImmutableArray(); GetState(); }
/// <summary> /// TBD /// </summary> /// <param name="typeName">TBD</param> /// <param name="shardId">TBD</param> /// <param name="entityProps">TBD</param> /// <param name="settings">TBD</param> /// <param name="extractEntityId">TBD</param> /// <param name="extractShardId">TBD</param> /// <param name="handOffStopMessage">TBD</param> public Shard( IActorContext context, Action <object> unhandled, string typeName, string shardId, Props entityProps, ClusterShardingSettings settings, ExtractEntityId extractEntityId, ExtractShardId extractShardId, object handOffStopMessage) { _context = context; _unhandled = unhandled; TypeName = typeName; ShardId = shardId; EntityProps = entityProps; Settings = settings; ExtractEntityId = extractEntityId; ExtractShardId = extractShardId; HandOffStopMessage = handOffStopMessage; Initialized(); }
public RememberEntityStarter( IActorRef region, string typeName, ShardId shardId, IImmutableSet <EntityId> ids, ClusterShardingSettings settings, IActorRef requestor ) { _region = region; _typeName = typeName; _shardId = shardId; _ids = ids; _settings = settings; _requestor = requestor; _waitingForAck = ids; SendStart(ids); var resendInterval = settings.TunningParameters.RetryInterval; _tickTask = Context.System.Scheduler.ScheduleTellRepeatedlyCancelable(resendInterval, resendInterval, Self, Tick.Instance, ActorRefs.NoSender); }
public ShardMetadataImpl(ShardId shardId, ISessionFactoryImplementor sessionFactory) : this(new[] { shardId }, sessionFactory) {}
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> public ShardHomeDeallocated(string shard) { Shard = shard; }
public RestartShard(string shardId) { ShardId = shardId; }
public static Actor.Props Props(ShardId shard, IActorRef replyTo, IEnumerable <IActorRef> entities, object stopMessage) { return(Actor.Props.Create(() => new HandOffStopper(shard, replyTo, entities, stopMessage)).WithDeploy(Deploy.Local)); }
private void InitializeShard(ShardId id, IActorRef shardRef) { Log.Debug("Shard was initialized [{0}]", id); Shards = Shards.SetItem(id, shardRef); DeliverBufferedMessage(id, shardRef); }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> /// <param name="ref">TBD</param> public ShardHome(string shard, IActorRef @ref) { Shard = shard; Ref = @ref; }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> /// <param name="shardRegion">TBD</param> /// <param name="getShardHomeSender">TBD</param> public AllocateShardResult(string shard, IActorRef shardRegion, IActorRef getShardHomeSender) { Shard = shard; ShardRegion = shardRegion; GetShardHomeSender = getShardHomeSender; }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> /// <param name="region">TBD</param> public ShardHomeAllocated(string shard, IActorRef region) { Shard = shard; Region = region; }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> public ShardStopped(string shard) { Shard = shard; }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> public HandOff(string shard) { Shard = shard; }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> public BeginHandOffAck(string shard) { Shard = shard; }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> public ShardStarted(string shard) { Shard = shard; }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> public HostShard(string shard) { Shard = shard; }
public static Actor.Props Props(string typeName, ShardId shardId, Props entryProps, ClusterShardingSettings settings, IdExtractor idExtractor, ShardResolver shardResolver, object handOffStopMessage) { return(Actor.Props.Create(() => new PersistentShard(typeName, shardId, entryProps, settings, idExtractor, shardResolver, handOffStopMessage)).WithDeploy(Deploy.Local)); }
/// <summary> /// TBD /// </summary> /// <param name="shard">TBD</param> public GetShardHome(string shard) { Shard = shard; }