예제 #1
0
        public InboxDirective ProcessTerminated(ProcessId pid)
        {
            if (termFn == null)
            {
                return(InboxDirective.Default);
            }

            lock (sync)
            {
                var savedReq   = ActorContext.CurrentRequest;
                var savedFlags = ActorContext.ProcessFlags;
                var savedMsg   = ActorContext.CurrentMsg;

                try
                {
                    ActorContext.CurrentRequest = null;
                    ActorContext.ProcessFlags   = flags;
                    ActorContext.CurrentMsg     = pid;

                    //ActorContext.AssertSession();

                    var stateIn  = GetState();
                    var stateOut = termFn(GetState(), pid);
                    state = stateOut;

                    try
                    {
                        if (notnull(stateOut) && !state.Equals(stateIn))
                        {
                            stateSubject.OnNext(stateOut);
                        }
                    }
                    catch (Exception ue)
                    {
                        // Not our errors, so just log and move on
                        logErr(ue);
                    }

                    strategyState = strategyState.With(
                        Failures: 0,
                        LastFailure: DateTime.MaxValue,
                        BackoffAmount: 0 * seconds
                        );

                    ActorContext.RunContextOps();
                }
                catch (Exception e)
                {
                    return(DefaultErrorHandler(pid, e));
                }
                finally
                {
                    ActorContext.CurrentRequest = savedReq;
                    ActorContext.ProcessFlags   = savedFlags;
                    ActorContext.CurrentMsg     = savedMsg;
                }
                return(InboxDirective.Default);
            }
        }
예제 #2
0
        /// <summary>
        /// Process an inbox message
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public InboxDirective ProcessMessage(object message)
        {
            lock (sync)
            {
                var savedReq   = ActorContext.CurrentRequest;
                var savedFlags = ActorContext.ProcessFlags;
                var savedMsg   = ActorContext.CurrentMsg;

                try
                {
                    ActorContext.CurrentRequest = null;
                    ActorContext.ProcessFlags   = flags;
                    ActorContext.CurrentMsg     = message;

                    //ActorContext.AssertSession();

                    if (typeof(T) != typeof(string) && message is string)
                    {
                        state = PreProcessMessageContent(message).Match(
                            Some: tmsg =>
                        {
                            var stateIn  = GetState();
                            var stateOut = actorFn(stateIn, tmsg);
                            try
                            {
                                if (notnull(stateOut) && !stateOut.Equals(stateIn))
                                {
                                    stateSubject.OnNext(stateOut);
                                }
                            }
                            catch (Exception ue)
                            {
                                // Not our errors, so just log and move on
                                logErr(ue);
                            }
                            return(stateOut);
                        },
                            None: () => state
                            );
                    }
                    else if (message is T)
                    {
                        var stateIn  = GetState();
                        var stateOut = actorFn(GetState(), (T)message);
                        state = stateOut;
                        try
                        {
                            if (notnull(stateOut) && !state.Equals(stateIn))
                            {
                                stateSubject.OnNext(stateOut);
                            }
                        }
                        catch (Exception ue)
                        {
                            // Not our errors, so just log and move on
                            logErr(ue);
                        }
                    }
                    else if (message is Message)
                    {
                        ProcessSystemMessage((Message)message);
                    }
                    else
                    {
                        logErr($"Can't tell {Id.Path}, message is not {typeof(T).GetTypeInfo().Name} : {message}");
                        return(InboxDirective.Default);
                    }

                    strategyState = strategyState.With(
                        Failures: 0,
                        LastFailure: DateTime.MaxValue,
                        BackoffAmount: 0 * seconds
                        );
                }
                catch (Exception e)
                {
                    return(DefaultErrorHandler(message, e));
                }
                finally
                {
                    ActorContext.CurrentRequest = savedReq;
                    ActorContext.ProcessFlags   = savedFlags;
                    ActorContext.CurrentMsg     = savedMsg;
                }
                return(InboxDirective.Default);
            }
        }