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);
        }
Ejemplo n.º 2
0
        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--;
            }
        }
Ejemplo n.º 3
0
        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);
Ejemplo n.º 5
0
 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)
     );
Ejemplo n.º 6
0
        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--;
                }
            }
        }
Ejemplo n.º 7
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;
                }
            });
        }
Ejemplo n.º 8
0
        /// <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);
            }
        }
Ejemplo n.º 9
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;
            }
        }
        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;
            }));
        }
Ejemplo n.º 11
0
 public Unit Kill() =>
 ActorContext.WithContext(new ActorItem(Actor, (IActorInbox)Inbox, Actor.Flags), Actor.Parent, ProcessId.NoSender, null, SystemMessage.ShutdownProcess, () =>
                          Actor.ShutdownProcess()
                          );