Пример #1
0
        /// <summary>
        /// Shutdown everything from this node down
        /// </summary>
        public Unit Shutdown(bool maintainState)
        {
            lock (sync)
            {
                if (maintainState == false)
                {
                    cluster.IfSome(c =>
                    {
                        // TODO: Make this transactional
                        // {
                        c.Delete(StateKey);
                        c.Delete(ActorInboxCommon.ClusterUserInboxKey(Id));
                        c.Delete(ActorInboxCommon.ClusterSystemInboxKey(Id));
                        c.Delete(ActorInboxCommon.ClusterMetaDataKey(Id));
                        ActorContext.DeregisterById(Id);
                        // }
                    });
                }

                RemoveAllSubscriptions();
                publishSubject.OnCompleted();
                stateSubject.OnCompleted();
                remoteSubsAcquired = false;
                strategyState      = StrategyState.Empty;
                DisposeState();

                ActorContext.DispatchTerminate(Id);

                return(unit);
            }
        }
        void ValidateMessageType(object message, ProcessId sender)
        {
            if (message == null)
            {
                throw new ProcessException($"Invalid message.  Null is not allowed for Process ({ProcessId}).", ProcessId.Path, sender.Path, null);
            }
            if (message is TerminatedMessage || message is UserControlMessage || message is SystemMessage)
            {
                return;
            }
            if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId)))
            {
                Try <bool> valid = () =>
                {
                    var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId));
                    return(meta == null || meta.MsgTypeNames == null
                        ? true
                        : meta.MsgTypeNames.Fold(false, (value, typ) =>
                    {
                        var lhsType = Type.GetType(typ)?.GetTypeInfo();
                        var rhsType = message.GetType().GetTypeInfo();

                        return value
                                    ? true
                                    : lhsType.IsAssignableFrom(rhsType);
                    }));
                };

                if (!valid.IfFail(true))
                {
                    throw new ProcessException($"Invalid message-type ({message.GetType().Name}) for Process ({ProcessId}).", ProcessId.Path, sender.Path, null);
                }
            }
        }
        public Unit Startup(IActor process, ActorItem parent, Option <ICluster> cluster, int maxMailboxSize)
        {
            if (cluster.IsNone)
            {
                throw new Exception("Remote inboxes not supported when there's no cluster");
            }
            this.tokenSource = new CancellationTokenSource();
            this.actor       = (Actor <S, T>)process;
            this.cluster     = cluster.LiftUnsafe();

            this.maxMailboxSize = maxMailboxSize;
            this.parent         = parent;

            userNotify = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ActorInboxCommon.ClusterUserInboxKey(actor.Id), true));
            sysNotify  = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ActorInboxCommon.ClusterSystemInboxKey(actor.Id), false));

            SubscribeToSysInboxChannel();
            SubscribeToUserInboxChannel();

            this.cluster.SetValue(ActorInboxCommon.ClusterMetaDataKey(actor.Id), new ProcessMetaData(
                                      new[] { typeof(T).AssemblyQualifiedName },
                                      typeof(S).AssemblyQualifiedName,
                                      typeof(S).GetTypeInfo().ImplementedInterfaces.Map(x => x.AssemblyQualifiedName).ToArray()
                                      ));

            return(unit);
        }
        public bool CanAccept <T>()
        {
            Try <bool> valid = () =>
            {
                if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId)))
                {
                    if (typeof(T) == typeof(TerminatedMessage) || typeof(T) == typeof(UserControlMessage) || typeof(T) == typeof(SystemMessage))
                    {
                        return(true);
                    }
                    var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId));
                    return(meta == null || meta.MsgTypeNames == null
                        ? true
                        : meta.MsgTypeNames.Fold(false, (value, typ) =>
                    {
                        var lhsType = Type.GetType(typ)?.GetTypeInfo();
                        var rhsType = typeof(T).GetTypeInfo();

                        return value
                                ? true
                                : lhsType.IsAssignableFrom(rhsType);
                    }));
                }
                else
                {
                    return(true);
                }
            };

            return(valid.IfFail(true));
        }
        public Unit Startup(IActor process, ActorItem parent, Option <ICluster> cluster, int maxMailboxSize)
        {
            if (cluster.IsNone)
            {
                throw new Exception("Remote inboxes not supported when there's no cluster");
            }
            this.tokenSource    = new CancellationTokenSource();
            this.actor          = (Actor <S, T>)process;
            this.cluster        = cluster.LiftUnsafe();
            this.maxMailboxSize = maxMailboxSize < 0
                ? ActorConfig.Default.MaxMailboxSize
                : maxMailboxSize;
            this.parent = parent;

            actorPath = actor.Id.ToString();

            userNotify = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ClusterUserInboxKey, true));
            sysNotify  = ActorInboxCommon.StartNotifyMailbox(tokenSource.Token, msgId => CheckRemoteInbox(ClusterSystemInboxKey, false));

            SubscribeToSysInboxChannel();
            SubscribeToUserInboxChannel();

            this.cluster.SetValue(ActorInboxCommon.ClusterMetaDataKey(actor.Id), new ProcessMetaData(
                                      new[] { typeof(T).FullName },
                                      typeof(S).FullName
                                      ));

            return(unit);
        }
Пример #6
0
 public Either <string, bool> CanAccept <T>()
 {
     if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId)))
     {
         var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId));
         return(meta == null
             ? true
             : TypeHelper.IsMessageValidForProcess(typeof(T), meta.MsgTypeNames).Map(_ => true));
     }
     else
     {
         return(true);
     }
 }
Пример #7
0
        void ValidateMessageType(object message, ProcessId sender)
        {
            if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId)))
            {
                var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId));
                if (meta == null)
                {
                    return;
                }

                TypeHelper.IsMessageValidForProcess(message, meta.MsgTypeNames).IfLeft((string err) =>
                {
                    throw new ProcessException($"{err} for Process ({ProcessId}).", ProcessId.Path, sender.Path, null);
                });
            }
        }
Пример #8
0
        public Either <string, bool> HasStateTypeOf <T>()
        {
            if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId)))
            {
                var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId));
                if (meta == null)
                {
                    return(true);
                }

                return(TypeHelper.HasStateTypeOf(typeof(T), meta.StateTypeInterfaces));
            }
            else
            {
                return(true);
            }
        }
Пример #9
0
        /// <summary>
        /// Shutdown everything from this node down
        /// </summary>
        public Unit Shutdown(bool maintainState)
        {
            lock (sync)
            {
                if (maintainState == false && Flags != ProcessFlags.Default)
                {
                    cluster.IfSome(c =>
                    {
                        // TODO: Make this transactional
                        // {
                        c.DeleteMany(
                            StateKey,
                            ActorInboxCommon.ClusterUserInboxKey(Id),
                            ActorInboxCommon.ClusterSystemInboxKey(Id),
                            ActorInboxCommon.ClusterMetaDataKey(Id),
                            ActorInboxCommon.ClusterSettingsKey(Id));

                        ActorContext.DeregisterById(Id);
                        // }

                        ProcessConfig.Settings.ClearInMemorySettingsOverride(ActorInboxCommon.ClusterSettingsKey(Id));
                    });
                }

                RemoveAllSubscriptions();
                publishSubject.OnCompleted();
                stateSubject.OnCompleted();
                remoteSubsAcquired = false;
                strategyState      = StrategyState.Empty;
                DisposeState();

                ActorContext.DispatchTerminate(Id);

                return(unit);
            }
        }
        public bool HasStateTypeOf <T>()
        {
            Try <bool> valid = () =>
            {
                if (Cluster.Exists(ActorInboxCommon.ClusterMetaDataKey(ProcessId)))
                {
                    var meta = Cluster.GetValue <ProcessMetaData>(ActorInboxCommon.ClusterMetaDataKey(ProcessId));

                    var rhsType = meta == null
                        ? null
                        : Type.GetType(meta.StateTypeName)?.GetTypeInfo();

                    return(meta == null || rhsType == null
                        ? true
                        : typeof(T).GetTypeInfo().IsAssignableFrom(rhsType));
                }
                else
                {
                    return(true);
                }
            };

            return(valid.IfFail(true));
        }