Example #1
0
        InboxDirective StatefulUserInbox(Actor <S, T> actor, IActorInbox inbox, UserControlMessage msg, ActorItem parent)
        {
            if (IsPaused)
            {
                userQueue = userQueue.Enqueue(msg);
            }
            else
            {
                while (userQueue.Count > 0)
                {
                    // Don't process messages if we've been paused
                    if (IsPaused)
                    {
                        return(InboxDirective.Pause);
                    }

                    var qmsg = userQueue.Peek();
                    userQueue = userQueue.Dequeue();
                    ProcessInboxDirective(ActorInboxCommon.UserMessageInbox(actor, inbox, qmsg, parent), qmsg);
                }

                if (IsPaused)
                {
                    // Don't process the message if we've been paused
                    userQueue = userQueue.Enqueue(msg);
                    return(InboxDirective.Pause);
                }

                return(ProcessInboxDirective(ActorInboxCommon.UserMessageInbox(actor, inbox, msg, parent), msg));
            }
            return(InboxDirective.Default);
        }
Example #2
0
        public ActorSystemBootstrap(IActorSystem system, Option <ICluster> cluster, ProcessId rootId, IActor rootProcess, IActorInbox rootInbox, ProcessName rootProcessName, ActorSystemConfig config, ProcessSystemConfig settings, SessionSync sync)
        {
            System = system;
            Sync   = sync;

            var parent = new ActorItem(new NullProcess(system.Name), new NullInbox(), ProcessFlags.Default);

            rootProcess = new Actor <ActorSystemBootstrap, Unit>(
                cluster,
                parent,
                rootProcessName,
                SystemInbox,
                _ => this,
                null,
                Process.DefaultStrategy,
                ProcessFlags.Default,
                settings,
                system
                );

            root            = new ActorItem(rootProcess, rootInbox, rootProcess.Flags);
            Config          = config;
            Settings        = settings;
            Cluster         = cluster;
            RootProcess     = rootProcess;
            RootInbox       = rootInbox;
            RootProcessName = rootProcessName;
        }
        public static InboxDirective UserMessageInbox <S, T>(Actor <S, T> actor, IActorInbox inbox, UserControlMessage msg, ActorItem parent)
        {
            switch (msg.Tag)
            {
            case Message.TagSpec.UserAsk:
                var rmsg = (ActorRequest)msg;
                return(ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, rmsg.ReplyTo, rmsg, msg, msg.SessionId, () => actor.ProcessAsk(rmsg)));

            case Message.TagSpec.UserReply:
                var urmsg = (ActorResponse)msg;
                ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, urmsg.ReplyFrom, null, msg, msg.SessionId, () => actor.ProcessResponse(urmsg));
                break;

            case Message.TagSpec.UserTerminated:
                var utmsg = (TerminatedMessage)msg;
                return(ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, utmsg.Id, null, msg, msg.SessionId, () => actor.ProcessTerminated(utmsg.Id)));

            case Message.TagSpec.User:
                var umsg = (UserMessage)msg;
                return(ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, umsg.Sender, null, msg, msg.SessionId, () => actor.ProcessMessage(umsg.Content)));

            case Message.TagSpec.ShutdownProcess:
                kill(actor.Id);
                break;
            }
            return(InboxDirective.Default);
        }
        InboxDirective StatefulUserInbox(Actor <S, T> actor, IActorInbox inbox, UserControlMessage msg, ActorItem parent)
        {
            if (IsPaused)
            {
                userQueue = userQueue.Enqueue(msg);
            }
            else
            {
                while (userQueue.Count > 0)
                {
                    var qmsg = userQueue.Peek();
                    userQueue = userQueue.Dequeue();
                    ActorInboxCommon.UserMessageInbox(actor, inbox, qmsg, parent);
                }
                var directive = ActorInboxCommon.UserMessageInbox(actor, inbox, msg, parent);

                if (directive == InboxDirective.PushToFrontOfQueue)
                {
                    var newQueue = Que <UserControlMessage> .Empty;

                    while (userQueue.Count > 0)
                    {
                        newQueue = newQueue.Enqueue(userQueue.Peek());
                        userQueue.Dequeue();
                    }

                    userQueue = newQueue;
                }
            }
            return(InboxDirective.Default);
        }
Example #5
0
 public ActorItem(
     IActor actor,
     IActorInbox inbox,
     ProcessFlags flags
     )
 {
     Actor = actor;
     Inbox = inbox;
     Flags = flags;
 }
Example #6
0
 public ActorItem(
     IActor actor,
     IActorInbox inbox,
     ProcessFlags flags
     )
 {
     Actor = actor;
     Inbox = inbox;
     Flags = flags;
 }
Example #7
0
        private static void ShutdownProcessRec(ActorItem item, IActorInbox inboxShutdown)
        {
            var process = item.Actor;
            var inbox   = item.Inbox;

            foreach (var child in process.Children.Values)
            {
                ShutdownProcessRec(child, inboxShutdown);
            }
            ((ILocalActorInbox)inboxShutdown).Tell(inbox, ProcessId.NoSender);
            process.Shutdown();
        }
Example #8
0
        public static ProcessId ActorCreate <S, T>(
            ActorItem parent,
            ProcessName name,
            Func <S, T, S> actorFn,
            Func <IActor, S> setupFn,
            Func <S, ProcessId, S> termFn,
            State <StrategyContext, Unit> strategy,
            ProcessFlags flags,
            int maxMailboxSize,
            bool lazy)
        {
            var actor = new Actor <S, T>(cluster, parent, name, actorFn, setupFn, termFn, strategy, flags);

            IActorInbox inbox = null;

            if ((flags & ProcessFlags.ListenRemoteAndLocal) == ProcessFlags.ListenRemoteAndLocal && cluster.IsSome)
            {
                inbox = new ActorInboxDual <S, T>();
            }
            else if ((flags & ProcessFlags.PersistInbox) == ProcessFlags.PersistInbox && cluster.IsSome)
            {
                inbox = new ActorInboxRemote <S, T>();
            }
            else
            {
                inbox = new ActorInboxLocal <S, T>();
            }

            var item = new ActorItem(actor, inbox, flags);

            parent.Actor.LinkChild(item);

            try
            {
                inbox.Startup(actor, parent, cluster, maxMailboxSize);
                if (!lazy)
                {
                    TellSystem(actor.Id, SystemMessage.StartupProcess);
                }
            }
            catch
            {
                item?.Actor?.ShutdownProcess(false);
                throw;
            }
            return(item.Actor.Id);
        }
Example #9
0
        public ActorItem ActorCreate <S, T>(ActorItem parent, ProcessName name, Func <S, T, S> actorFn, Func <S> setupFn, Func <S, ProcessId, S> termFn, ProcessFlags flags, int maxMailboxSize = -1)
        {
            if (ProcessDoesNotExist(nameof(ActorCreate), parent.Actor.Id))
            {
                return(null);
            }

            var actor = new Actor <S, T>(Cluster, parent, name, actorFn, _ => setupFn(), termFn, Process.DefaultStrategy, flags, Settings, System);

            IActorInbox inbox = null;

            if ((actor.Flags & ProcessFlags.ListenRemoteAndLocal) == ProcessFlags.ListenRemoteAndLocal && Cluster.IsSome)
            {
                inbox = new ActorInboxDual <S, T>();
            }
            else if ((actor.Flags & ProcessFlags.PersistInbox) == ProcessFlags.PersistInbox && Cluster.IsSome)
            {
                inbox = new ActorInboxRemote <S, T>();
            }
            else
            {
                inbox = new ActorInboxLocal <S, T>();
            }

            var item = new ActorItem(actor, inbox, actor.Flags);

            try
            {
                parent.Actor.LinkChild(item);
                inbox.Startup(actor, actor.Parent, Cluster,
                              maxMailboxSize == -1
                        ? Settings.GetProcessMailboxSize(actor.Id)
                        : maxMailboxSize
                              );
            }
            catch (Exception e)
            {
                item.Actor.ShutdownProcess(false);
                logSysErr(new ProcessException($"Process failed starting up: {e.Message}", actor.Id.Path, actor.Parent.Actor.Id.Path, e));
            }

            return(item);
        }
Example #10
0
        public ActorItem ActorCreate <S, T>(ActorItem parent, ProcessName name, Func <S, T, S> actorFn, Func <S> setupFn, ProcessFlags flags)
        {
            if (ProcessDoesNotExist(nameof(ActorCreate), parent.Actor.Id))
            {
                return(null);
            }

            var actor = new Actor <S, T>(Cluster, parent, name, actorFn, setupFn, flags);

            IActorInbox inbox = null;

            if ((flags & ProcessFlags.ListenRemoteAndLocal) == ProcessFlags.ListenRemoteAndLocal && Cluster.IsSome)
            {
                inbox = new ActorInboxDual <S, T>();
            }
            else if ((flags & ProcessFlags.PersistInbox) == ProcessFlags.PersistInbox && Cluster.IsSome)
            {
                inbox = new ActorInboxRemote <S, T>();
            }
            else
            {
                inbox = new ActorInboxLocal <S, T>();
            }

            var item = new ActorItem(actor, inbox, flags);

            try
            {
                parent.Actor.LinkChild(item);
                actor.Startup();
                inbox.Startup(actor, actor.Parent, Cluster, 0);
            }
            catch (Exception e)
            {
                ShutdownProcess(item.Actor.Id);
                logSysErr(new ProcessException("Process failed starting up: " + e.Message, actor.Id.Path, actor.Parent.Actor.Id.Path, e));
            }

            return(item);
        }
Example #11
0
        public ActorSystemState(Option <ICluster> cluster, ProcessId rootId, IActor rootProcess, IActorInbox rootInbox, ProcessName rootProcessName, ActorSystemConfig config)
        {
            var parent = new ActorItem(new NullProcess(), new NullInbox(), ProcessFlags.Default);

            rootProcess = new Actor <ActorSystemState, Unit>(
                cluster,
                parent,
                rootProcessName,
                ActorSystem.Inbox,
                _ => this,
                null,
                Process.DefaultStrategy,
                ProcessFlags.Default
                );

            root            = new ActorItem(rootProcess, RootInbox, rootProcess.Flags);
            Config          = config;
            Cluster         = cluster;
            RootProcess     = rootProcess;
            RootInbox       = rootInbox;
            RootProcessName = rootProcessName;
        }
        public static void SystemMessageInbox <S, T>(Actor <S, T> actor, IActorInbox inbox, SystemMessage msg, ActorItem parent)
        {
            ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, ProcessId.NoSender, null, msg, () =>
            {
                switch (msg.Tag)
                {
                case Message.TagSpec.Restart:
                    actor.Restart();
                    break;

                case Message.TagSpec.LinkChild:
                    var lc = msg as SystemLinkChildMessage;
                    actor.LinkChild(lc.Child);
                    break;

                case Message.TagSpec.UnlinkChild:
                    var ulc = msg as SystemUnLinkChildMessage;
                    actor.UnlinkChild(ulc.Child);
                    break;
                }
            });
        }
Example #13
0
        public ActorSystemState(Option <ICluster> cluster, ProcessId rootId, IActor rootProcess, IActorInbox rootInbox, ProcessName rootProcessName, ActorConfig config)
        {
            var parent = new ActorItem(new NullProcess(), new NullInbox(), ProcessFlags.Default);

            rootProcess = new Actor <ActorSystemState, Unit>(
                cluster,
                parent,
                rootProcessName,
                ActorSystem.Inbox,
                () => this,
                ProcessFlags.Default
                );

            root            = new ActorItem(rootProcess, RootInbox, rootProcess.Flags);
            Config          = config;
            Cluster         = cluster;
            RootProcess     = rootProcess;
            RootInbox       = rootInbox;
            RootProcessName = rootProcessName;

            RootProcess.Id.Child(Config.RegisteredProcessName);
        }
Example #14
0
        public static ProcessId ActorCreate <S, T>(ActorItem parent, ProcessName name, Func <S, T, S> actorFn, Func <S> setupFn, ProcessFlags flags)
        {
            var actor = new Actor <S, T>(cluster, parent, name, actorFn, setupFn, flags);

            IActorInbox inbox = null;

            if ((flags & ProcessFlags.ListenRemoteAndLocal) == ProcessFlags.ListenRemoteAndLocal && cluster.IsSome)
            {
                inbox = new ActorInboxDual <S, T>();
            }
            else if ((flags & ProcessFlags.PersistInbox) == ProcessFlags.PersistInbox && cluster.IsSome)
            {
                inbox = new ActorInboxRemote <S, T>();
            }
            else
            {
                inbox = new ActorInboxLocal <S, T>();
            }

            var item = new ActorItem(actor, inbox, flags);

            parent.Actor.LinkChild(item);

            try
            {
                if (!started)
                {
                    actor.Startup();
                }
                inbox.Startup(actor, parent, cluster, 0);
            }
            catch
            {
                ShutdownProcess(item);
                throw;
            }
            return(item.Actor.Id);
        }
        public static void UserMessageInbox <S, T>(Actor <S, T> actor, IActorInbox inbox, UserControlMessage msg, ActorItem parent)
        {
            switch (msg.Tag)
            {
            case Message.TagSpec.UserAsk:
                var rmsg = (ActorRequest)msg;
                ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, rmsg.ReplyTo, rmsg, msg, () => actor.ProcessAsk(rmsg));
                break;

            case Message.TagSpec.UserReply:
                var urmsg = (ActorResponse)msg;
                ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, urmsg.ReplyFrom, null, msg, () => actor.ProcessResponse(urmsg));
                break;

            case Message.TagSpec.User:
                var umsg = (UserMessage)msg;
                ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, umsg.Sender, null, msg, () => actor.ProcessMessage(umsg.Content));
                break;

            case Message.TagSpec.ShutdownProcess:
                kill(actor.Id);
                break;
            }
        }
        public static InboxDirective SystemMessageInbox <S, T>(Actor <S, T> actor, IActorInbox inbox, SystemMessage msg, ActorItem parent)
        {
            return(ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, ProcessId.NoSender, null, msg, msg.SessionId, () =>
            {
                switch (msg.Tag)
                {
                case Message.TagSpec.Restart:
                    if (inbox.IsPaused)
                    {
                        inbox.Unpause();
                    }
                    actor.Restart();
                    break;

                case Message.TagSpec.LinkChild:
                    var lc = msg as SystemLinkChildMessage;
                    actor.LinkChild(lc.Child);
                    break;

                case Message.TagSpec.UnlinkChild:
                    var ulc = msg as SystemUnLinkChildMessage;
                    actor.UnlinkChild(ulc.Child);
                    break;

                case Message.TagSpec.ChildFaulted:
                    var cf = msg as SystemChildFaultedMessage;
                    return actor.ChildFaulted(cf.Child, cf.Sender, cf.Exception, cf.Message);

                case Message.TagSpec.StartupProcess:
                    actor.Startup();
                    break;

                case Message.TagSpec.ShutdownProcess:
                    var sp = msg as ShutdownProcessMessage;
                    actor.ShutdownProcess(sp.MaintainState);
                    break;

                case Message.TagSpec.Unpause:
                    inbox.Unpause();
                    break;

                case Message.TagSpec.Pause:
                    inbox.Pause();
                    break;

                case Message.TagSpec.Watch:
                    var awm = msg as SystemAddWatcherMessage;
                    actor.AddWatcher(awm.Id);
                    break;

                case Message.TagSpec.UnWatch:
                    var rwm = msg as SystemRemoveWatcherMessage;
                    actor.RemoveWatcher(rwm.Id);
                    break;

                case Message.TagSpec.DispatchWatch:
                    var dwm = msg as SystemDispatchWatchMessage;
                    actor.DispatchWatch(dwm.Id);
                    break;

                case Message.TagSpec.DispatchUnWatch:
                    var duwm = msg as SystemDispatchUnWatchMessage;
                    actor.DispatchUnWatch(duwm.Id);
                    break;
                }
                return InboxDirective.Default;
            }));
        }
Example #17
0
        public static InboxDirective SystemMessageInbox <S, T>(Actor <S, T> actor, IActorInbox inbox, SystemMessage msg, ActorItem parent)
        {
            var session = msg.SessionId == null
                ? None
                : Some(new SessionId(msg.SessionId));

            return(ActorContext.System(actor.Id).WithContext(new ActorItem(actor, inbox, actor.Flags), parent, ProcessId.NoSender, null, msg, session, () =>
            {
                switch (msg.Tag)
                {
                case Message.TagSpec.Restart:
                    actor.Restart(inbox.IsPaused);
                    break;

                case Message.TagSpec.LinkChild:
                    var lc = msg as SystemLinkChildMessage;
                    actor.LinkChild(lc.Child);
                    break;

                case Message.TagSpec.UnlinkChild:
                    var ulc = (msg as SystemUnLinkChildMessage).SetSystem(actor.Id.System);
                    actor.UnlinkChild(ulc.Child);
                    break;

                case Message.TagSpec.ChildFaulted:
                    var cf = (msg as SystemChildFaultedMessage).SetSystem(actor.Id.System);
                    return actor.ChildFaulted(cf.Child, cf.Sender, cf.Exception, cf.Message);

                case Message.TagSpec.StartupProcess:
                    var startupProcess = msg as StartupProcessMessage;
                    var inboxDirective = actor.Startup();     // get feedback whether startup will somehow trigger Unpause itself (i.e. error => strategy => restart)
                    if (startupProcess.UnpauseAfterStartup && !inboxDirective.HasFlag(InboxDirective.Pause))
                    {
                        inbox.Unpause();
                    }
                    break;

                case Message.TagSpec.ShutdownProcess:
                    var shutdownProcess = msg as ShutdownProcessMessage;
                    actor.ShutdownProcess(shutdownProcess.MaintainState);
                    break;

                case Message.TagSpec.Unpause:
                    inbox.Unpause();
                    break;

                case Message.TagSpec.Pause:
                    inbox.Pause();
                    break;     // do not return InboxDirective.Pause because system queue should never pause

                case Message.TagSpec.Watch:
                    var awm = msg as SystemAddWatcherMessage;
                    actor.AddWatcher(awm.Id);
                    break;

                case Message.TagSpec.UnWatch:
                    var rwm = msg as SystemRemoveWatcherMessage;
                    actor.RemoveWatcher(rwm.Id);
                    break;

                case Message.TagSpec.DispatchWatch:
                    var dwm = msg as SystemDispatchWatchMessage;
                    actor.DispatchWatch(dwm.Id);
                    break;

                case Message.TagSpec.DispatchUnWatch:
                    var duwm = msg as SystemDispatchUnWatchMessage;
                    actor.DispatchUnWatch(duwm.Id);
                    break;
                }
                return InboxDirective.Default;
            }));
        }
 internal static ActorSystemMessage AddToStore(IActor process, IActorInbox inbox, ProcessFlags flags) =>
     new AddToStoreMessage(process, inbox, flags);
Example #19
0
        public ProcessId ActorCreate <S, T>(
            ActorItem parent,
            ProcessName name,
            Func <S, T, S> actorFn,
            Func <IActor, S> setupFn,
            Func <S, ProcessId, S> termFn,
            State <StrategyContext, Unit> strategy,
            ProcessFlags flags,
            int maxMailboxSize,
            bool lazy)
        {
            var actor = new Actor <S, T>(cluster, parent, name, actorFn, setupFn, termFn, strategy, flags, ActorContext.System(parent.Actor.Id).Settings, this);

            IActorInbox inbox = null;

            if ((actor.Flags & ProcessFlags.ListenRemoteAndLocal) == ProcessFlags.ListenRemoteAndLocal && cluster.IsSome)
            {
                inbox = new ActorInboxDual <S, T>();
            }
            else if ((actor.Flags & ProcessFlags.PersistInbox) == ProcessFlags.PersistInbox && cluster.IsSome)
            {
                inbox = new ActorInboxRemote <S, T>();
            }
            else
            {
                inbox = new ActorInboxLocal <S, T>();
            }

            var item = new ActorItem(actor, inbox, actor.Flags);

            parent.Actor.LinkChild(item);

            // Auto register if there are config settings and we
            // have the variable name it was assigned to.
            ActorContext.System(actor.Id).Settings.GetProcessRegisteredName(actor.Id).Iter(regName =>
            {
                // Also check if 'dispatch' is specified in the config, if so we will
                // register the Process as a role dispatcher PID instead of just its
                // PID.
                ActorContext.System(actor.Id).Settings.GetProcessDispatch(actor.Id)
                .Match(
                    Some: disp => Process.register(regName, Disp[$"role-{disp}"][Role.Current].Append(actor.Id.Skip(1))),
                    None: () => Process.register(regName, actor.Id)
                    );
            });

            try
            {
                inbox.Startup(actor, parent, cluster, maxMailboxSize);
                if (!lazy)
                {
                    TellSystem(actor.Id, SystemMessage.StartupProcess);
                }
            }
            catch
            {
                item?.Actor?.ShutdownProcess(false);
                throw;
            }
            return(item.Actor.Id);
        }
 public static ActorSystemMessage AddToStore(IProcess process, IActorInbox inbox, ProcessFlags flags) =>
     new AddToStoreMessage(process, inbox, flags);
 public AddToStoreMessage(IProcess process, IActorInbox inbox, ProcessFlags flags)
 {
     Process = process;
     Inbox = inbox;
     Flags = flags;
 }