public ActorRequestContext(
     ActorItem self,
     ProcessId sender,
     ActorItem parent,
     object currentMsg,
     ActorRequest currentRequest,
     ProcessFlags processFlags
     )
 {
     Self = self;
     Sender = sender;
     Parent = parent;
     CurrentMsg = currentMsg;
     CurrentRequest = currentRequest;
     ProcessFlags = processFlags;
 }
 public ActorRequestContext(
     ActorSystem system,
     ActorItem self,
     ProcessId sender,
     ActorItem parent,
     object currentMsg,
     ActorRequest currentRequest,
     ProcessFlags processFlags,
     ProcessOpTransaction ops,
     SessionVector session
     )
 {
     Self = self;
     Sender = sender;
     Parent = parent;
     CurrentMsg = currentMsg;
     CurrentRequest = currentRequest;
     ProcessFlags = processFlags;
     Ops = ops;
     System = system;
     Session = session;
 }
        public ActorSystem(SystemName systemName, Option <ICluster> cluster, AppProfile appProfile, ProcessSystemConfig settings)
        {
            var name = GetRootProcessName(cluster);

            if (name.Value == "root" && cluster.IsSome)
            {
                throw new ArgumentException("Cluster node name cannot be 'root', it's reserved for local use only.");
            }
            if (name.Value == "disp" && cluster.IsSome)
            {
                throw new ArgumentException("Cluster node name cannot be 'disp', it's reserved for internal use.");
            }
            if (name.Value == "js")
            {
                throw new ArgumentException("Node name cannot be 'js', it's reserved for ProcessJS.");
            }

            SystemName       = systemName;
            this.appProfile  = appProfile;
            this.settings    = settings;
            this.cluster     = cluster;
            startupTimestamp = DateTime.UtcNow.Ticks;
            sessionManager   = new SessionManager(cluster, SystemName, appProfile.NodeName, VectorConflictStrategy.Branch);
            watchers         = Map.empty <ProcessId, Set <ProcessId> >();
            watchings        = Map.empty <ProcessId, Set <ProcessId> >();

            startupSubscription = NotifyCluster(cluster, startupTimestamp);

            Dispatch.init();
            Role.init(cluster.Map(r => r.Role).IfNone("local"));
            Reg.init();

            var root      = ProcessId.Top.Child(GetRootProcessName(cluster));
            var rootInbox = new ActorInboxLocal <ActorSystemBootstrap, Unit>();
            var parent    = new ActorItem(new NullProcess(SystemName), new NullInbox(), ProcessFlags.Default);

            var state = new ActorSystemBootstrap(
                this,
                cluster,
                root, null,
                rootInbox,
                cluster.Map(x => x.NodeName).IfNone(ActorSystemConfig.Default.RootProcessName),
                ActorSystemConfig.Default,
                Settings,
                sessionManager.Sync
                );

            var rootProcess = state.RootProcess;

            state.Startup();
            rootItem    = new ActorItem(rootProcess, rootInbox, ProcessFlags.Default);
            userContext = new ActorRequestContext(
                this,
                rootProcess.Children["user"],
                ProcessId.NoSender,
                rootItem,
                null,
                null,
                ProcessFlags.Default,
                null,
                null);
            rootInbox.Startup(rootProcess, parent, cluster, settings.GetProcessMailboxSize(rootProcess.Id));
        }
Esempio n. 4
0
 public ActorDispatchJS(ProcessId pid, ProcessId relay, ActorItem js)
 {
     ProcessId = pid;
     RelayId   = relay;
     Js        = js;
 }
Esempio n. 5
0
 public Unit Startup(IActor pid, ActorItem parent, Option<ICluster> cluster, int maxMailboxSize) => unit;
Esempio n. 6
0
 public static SystemMessage LinkChild(ActorItem item) => new SystemLinkChildMessage(item);
Esempio n. 7
0
 public Unit Startup(IActor pid, ActorItem parent, Option<ICluster> cluster, int version) => unit;
        public static InboxDirective UserMessageInbox <S, T>(Actor <S, T> actor, IActorInbox inbox, UserControlMessage msg, ActorItem parent)
        {
            var session = msg.SessionId == null
                ? None
                : Some(new SessionId(msg.SessionId));

            switch (msg.Tag)
            {
            case Message.TagSpec.UserAsk:
                var rmsg = ((ActorRequest)msg).SetSystem(actor.Id.System);
                return(ActorContext.System(actor.Id).WithContext(new ActorItem(actor, inbox, actor.Flags), parent, rmsg.ReplyTo, rmsg, msg, session, () => actor.ProcessAsk(rmsg)));

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

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

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

            case Message.TagSpec.ShutdownProcess:
                kill(actor.Id);
                break;
            }
            return(InboxDirective.Default);
        }
 public Unit LinkChild(ActorItem item) => unit;
Esempio n. 10
0
 public static ProcessId ActorCreate <S, T>(ActorItem parent, ProcessName name, Action <T> actorFn, ProcessFlags flags) =>
 ActorCreate <S, T>(parent, name, (s, t) => { actorFn(t); return(default(S)); }, () => default(S), flags);
Esempio n. 11
0
 public Unit Startup(IActor pid, ActorItem parent, Option <ICluster> cluster, int version) => unit;
        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);
        }
Esempio n. 13
0
 public SystemLinkChildMessage(ActorItem child)
 {
     Child = child;
 }
Esempio n. 14
0
 public static SystemMessage LinkChild(ActorItem item) => new SystemLinkChildMessage(item);
Esempio n. 15
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);
        }
Esempio n. 16
0
 public Unit WithContext(ActorItem self, ActorItem parent, ProcessId sender, ActorRequest request, object msg, Option <SessionId> sessionId, Action f) =>
 WithContext(self, parent, sender, request, msg, sessionId, fun(f));
Esempio n. 17
0
 private static void ShutdownProcess(ActorItem item)
 {
     item.Actor.Parent.Actor.UnlinkChild(item.Actor.Id);
     GetInboxShutdownItem().IfSome(ibs => ShutdownProcessRec(item, ibs.Inbox));
 }
 public ActorItem ActorCreate <T>(ActorItem parent, ProcessName name, Action <T> actorFn, Func <Unit, ProcessId, Unit> termFn, ProcessFlags flags, int maxMailboxSize = -1)
 {
     return(ActorCreate <Unit, T>(parent, name, (s, t) => { actorFn(t); return unit; }, () => unit, termFn, flags, maxMailboxSize));
 }
Esempio n. 19
0
 public static Unit WithContext(ActorItem self, ActorItem parent, ProcessId sender, ActorRequest request, object msg, Action f) =>
 WithContext(self, parent, sender, request, msg, fun(f));
Esempio n. 20
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:
                    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).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:
                    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();
                    return InboxDirective.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;
            }));
        }
Esempio n. 21
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);
        }
Esempio n. 22
0
        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;
                }
            });
        }
Esempio n. 23
0
        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;
            }
        }
Esempio n. 24
0
 public SystemLinkChildMessage(ActorItem child)
 {
     Child = child;
 }
Esempio n. 25
0
 public ActorItem ActorCreate <T>(ActorItem parent, ProcessName name, Action <T> actorFn, ProcessFlags flags)
 {
     return(ActorCreate <Unit, T>(parent, name, (s, t) => { actorFn(t); return unit; }, () => unit, flags));
 }