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)); }
public ActorDispatchJS(ProcessId pid, ProcessId relay, ActorItem js) { ProcessId = pid; RelayId = relay; Js = js; }
public Unit Startup(IActor pid, ActorItem parent, Option<ICluster> cluster, int maxMailboxSize) => unit;
public static SystemMessage LinkChild(ActorItem item) => new SystemLinkChildMessage(item);
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;
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);
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); }
public SystemLinkChildMessage(ActorItem child) { Child = child; }
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 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));
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)); }
public static Unit WithContext(ActorItem self, ActorItem parent, ProcessId sender, ActorRequest request, object msg, Action f) => WithContext(self, parent, sender, request, msg, fun(f));
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; })); }
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); }
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; } }); }
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 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)); }