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); }
private void CheckRemoteInbox(string key) { var inbox = this; var count = cluster.QueueLength(key); while (count > 0) { ActorInboxCommon.GetNextMessage(cluster, actor.Id, key).IfSome( x => iter(x, (dto, msg) => { try { switch (msg.MessageType) { case Message.Type.System: ActorInboxCommon.SystemMessageInbox(actor, inbox, (SystemMessage)msg, parent); break; case Message.Type.User: ActorInboxCommon.UserMessageInbox(actor, inbox, (UserControlMessage)msg, parent); break; case Message.Type.UserControl: ActorInboxCommon.UserMessageInbox(actor, inbox, (UserControlMessage)msg, parent); break; } } catch (Exception e) { ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, dto.Sender, msg as ActorRequest, msg, () => replyErrorIfAsked(e)); tell(ActorContext.DeadLetters, DeadLetter.create(dto.Sender, actor.Id, e, "Remote message inbox.", msg)); logSysErr(e); } finally { cluster.Dequeue <RemoteMessageDTO>(key); } })); count--; } }
internal static IDisposable safedelay(Action f, TimeSpan delayFor) { var savedContext = ActorContext.Context; var savedSession = SessionManager.SessionId; return((IDisposable)Task.Delay(delayFor).ContinueWith(_ => { try { ActorContext.WithContext( savedContext.Self, savedContext.Parent, savedContext.Sender, savedContext.CurrentRequest, savedContext.CurrentMsg, savedSession, () => { f(); // Run the operations that affect the settings and sending of tells // in the order which they occured in the actor ActorContext.Context?.Ops?.Run(); } ); } catch (Exception e) { logErr(e); } })); }
/// <summary> /// Acquires a session for the duration of invocation of the /// provided function /// </summary> /// <param name="sid">Session ID</param> /// <param name="f">Function to invoke</param> /// <returns>Result of the function</returns> public static R withSession <R>(string sid, Func <R> f) => ActorContext.WithContext <R>( ActorContext.SelfProcess, ActorContext.SelfProcess.Actor.Parent, Process.Sender, ActorContext.CurrentRequest, ActorContext.CurrentMsg, Some(sid), f);
Unit ShutdownProcess(bool maintainState) => ActorContext.WithContext( new ActorItem( Actor, (IActorInbox)Inbox, Actor.Flags ), Actor.Parent, ProcessId.NoSender, null, SystemMessage.ShutdownProcess(maintainState), None, () => Actor.ShutdownProcess(maintainState) );
void CheckRemoteInbox(string key, bool pausable) { var inbox = this; var count = cluster?.QueueLength(key) ?? 0; while (count > 0 && (!pausable || !IsPaused)) { var directive = InboxDirective.Default; ActorInboxCommon.GetNextMessage(cluster, actor.Id, key).IfSome( x => iter(x, (dto, msg) => { try { switch (msg.MessageType) { case Message.Type.User: directive = ActorInboxCommon.UserMessageInbox(actor, inbox, (UserControlMessage)msg, parent); break; case Message.Type.UserControl: directive = ActorInboxCommon.UserMessageInbox(actor, inbox, (UserControlMessage)msg, parent); break; } } catch (Exception e) { ActorContext.WithContext(new ActorItem(actor, inbox, actor.Flags), parent, dto.Sender, msg as ActorRequest, msg, msg.SessionId, () => replyErrorIfAsked(e)); tell(ActorContext.DeadLetters, DeadLetter.create(dto.Sender, actor.Id, e, "Remote message inbox.", msg)); logSysErr(e); } finally { if ((directive & InboxDirective.Pause) != 0) { IsPaused = true; directive = directive & (~InboxDirective.Pause); } if (directive == InboxDirective.Default) { cluster?.Dequeue <RemoteMessageDTO>(key); } } })); if (directive == InboxDirective.Default) { count--; } } }
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; } }); }
/// <summary> /// TODO: This is a combination of code in ActorCommon.GetNextMessage and /// CheckRemoteInbox. Some factoring is needed. /// </summary> void SysInbox(RemoteMessageDTO dto) { try { if (dto == null) { // Failed to deserialise properly return; } if (dto.Tag == 0 && dto.Type == 0) { // Message is bad tell(ActorContext.DeadLetters, DeadLetter.create(dto.Sender, actor.Id, null, "Failed to deserialise message: ", dto)); return; } var msg = MessageSerialiser.DeserialiseMsg(dto, actor.Id); try { lock (sync) { ActorInboxCommon.SystemMessageInbox(actor, this, (SystemMessage)msg, parent); } } catch (Exception e) { ActorContext.WithContext(new ActorItem(actor, this, actor.Flags), parent, dto.Sender, msg as ActorRequest, msg, msg.SessionId, () => replyErrorIfAsked(e)); tell(ActorContext.DeadLetters, DeadLetter.create(dto.Sender, actor.Id, e, "Remote message inbox.", msg)); logSysErr(e); } } catch (Exception e) { logSysErr(e); } }
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; })); }
public Unit Kill() => ActorContext.WithContext(new ActorItem(Actor, (IActorInbox)Inbox, Actor.Flags), Actor.Parent, ProcessId.NoSender, null, SystemMessage.ShutdownProcess, () => Actor.ShutdownProcess() );