Esempio n. 1
0
        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;
        }
Esempio n. 3
0
 /// <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;
 }
Esempio n. 4
0
        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;
        }
Esempio n. 5
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)));
            }
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
                    }
                }
            }
        }
Esempio n. 8
0
        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));
        }
Esempio n. 9
0
        /// <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));
            }
        }
Esempio n. 12
0
 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));
     }
 }
Esempio n. 13
0
            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);
        }
Esempio n. 15
0
        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);
        }
Esempio n. 16
0
        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();
        }
Esempio n. 17
0
        /// <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();
        }
Esempio n. 18
0
        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);
        }
Esempio n. 19
0
 public ShardMetadataImpl(ShardId shardId, ISessionFactoryImplementor sessionFactory)
     : this(new[] { shardId }, sessionFactory)
 {}
 /// <summary>
 /// TBD
 /// </summary>
 /// <param name="shard">TBD</param>
 public ShardHomeDeallocated(string shard)
 {
     Shard = shard;
 }
Esempio n. 21
0
 public RestartShard(string shardId)
 {
     ShardId = shardId;
 }
Esempio n. 22
0
 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));
 }
Esempio n. 23
0
 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;
 }
Esempio n. 32
0
 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;
 }