Ejemplo n.º 1
0
        public R WithContext <R>(ActorItem self, ActorItem parent, ProcessId sender, ActorRequest request, object msg, Option <SessionId> sessionId, Func <R> f)
        {
            var savedContext = ActorContext.Request;
            var savedSession = ActorContext.SessionId;

            try
            {
                ActorContext.SessionId = sessionId;

                ActorContext.SetContext(
                    new ActorRequestContext(
                        this,
                        self,
                        sender,
                        parent,
                        msg,
                        request,
                        ProcessFlags.Default,
                        Settings.TransactionalIO
                            ? ProcessOpTransaction.Start(self.Actor.Id)
                            : null));

                return(f());
            }
            catch (Exception e)
            {
                logErr(e);
                throw;
            }
            finally
            {
                ActorContext.SessionId = savedSession;
                ActorContext.SetContext(savedContext);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Run the operations that affect the settings and sending of tells
 /// in the order which they occured in the actor
 /// </summary>
 public Unit RunOps()
 {
     if (Ops != null)
     {
         while (Ops.Ops.Count > 0)
         {
             var ops = Ops;
             Ops = ProcessOpTransaction.Start(Ops.ProcessId);
             ops.Run();
         }
     }
     return(unit);
 }
Ejemplo n.º 3
0
 public ActorRequestContext(
     ActorSystem system,
     ActorItem self,
     ProcessId sender,
     ActorItem parent,
     object currentMsg,
     ActorRequest currentRequest,
     ProcessFlags processFlags,
     ProcessOpTransaction ops
     )
 {
     Self           = self;
     Sender         = sender;
     Parent         = parent;
     CurrentMsg     = currentMsg;
     CurrentRequest = currentRequest;
     ProcessFlags   = processFlags;
     Ops            = ops;
     System         = system;
 }
Ejemplo n.º 4
0
        InboxDirective DefaultErrorHandler(object message, Exception e)
        {
            // Wipe all transactional outputs because of the error
            ActorContext.Request.SetOps(ProcessOpTransaction.Start(Id));

            var directive = RunStrategy(
                Id,
                Parent.Actor.Id,
                Sender,
                Parent.Actor.Children.Values.Map(n => n.Actor.Id).Filter(x => x != Id),
                e,
                message,
                Parent.Actor.Strategy
                );

            if (!(e is ProcessKillException))
            {
                tell(sys.Errors, e);
            }

            // Run any transactional outputs caused by the strategy computation
            ActorContext.Request.RunOps();
            return(directive);
        }
Ejemplo n.º 5
0
 public void SetOps(ProcessOpTransaction ops)
 {
     Ops = ops;
 }
Ejemplo n.º 6
0
        public InboxDirective ProcessAsk(ActorRequest request)
        {
            lock (sync)
            {
                if (cancellationTokenSource.IsCancellationRequested)
                {
                    replyError(new AskException(
                                   $"Can't ask {Id.Path} because actor shutdown in progress"));
                    return(InboxDirective.Shutdown);
                }

                var savedMsg   = ActorContext.Request.CurrentMsg;
                var savedFlags = ActorContext.Request.ProcessFlags;
                var savedReq   = ActorContext.Request.CurrentRequest;

                try
                {
                    ActorContext.Request.CurrentRequest = request;
                    ActorContext.Request.ProcessFlags   = flags;
                    ActorContext.Request.CurrentMsg     = request.Message;

                    //ActorContext.AssertSession();

                    if (typeof(T) != typeof(string) && request.Message is string)
                    {
                        state = PreProcessMessageContent(request.Message).Match(
                            Some: tmsg =>
                        {
                            var stateIn  = GetState();
                            var stateOut = actorFn(stateIn, tmsg);
                            try
                            {
                                if (!default(EqDefault <S>).Equals(stateOut, stateIn))
                                {
                                    stateSubject.OnNext(stateOut);
                                }
                            }
                            catch (Exception ue)
                            {
                                // Not our errors, so just log and move on
                                logErr(ue);
                            }

                            return(stateOut);
                        },
                            None: () =>
                        {
                            replyError(new AskException(
                                           $"Can't ask {Id.Path}, message is not {typeof(T).GetTypeInfo().Name} : {request.Message}"));
                            return(state);
                        }
                            );
                    }
                    else if (request.Message is T msg)
                    {
                        var stateIn  = GetState();
                        var stateOut = actorFn(stateIn, msg);
                        try
                        {
                            if (!default(EqDefault <S>).Equals(stateOut, stateIn))
                            {
                                stateSubject.OnNext(stateOut);
                            }
                        }
                        catch (Exception ue)
                        {
                            // Not our errors, so just log and move on
                            logErr(ue);
                        }

                        state = stateOut;
                    }
                    else if (request.Message is Message m)
                    {
                        ProcessSystemMessage(m);
                    }
                    else
                    {
                        // Failure to deserialise is not our problem, its the sender's
                        // so we don't throw here.
                        replyError(new AskException(
                                       $"Can't ask {Id.Path}, message is not {typeof(T).GetTypeInfo().Name} : {request.Message}"));
                        return(InboxDirective.Default);
                    }

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

                    ActorContext.Request.RunOps();
                }
                catch (Exception e)
                {
                    ActorContext.Request.SetOps(ProcessOpTransaction.Start(Id));
                    replyError(e);
                    ActorContext.Request.RunOps();
                    return(DefaultErrorHandler(request, e));
                }
                finally
                {
                    ActorContext.Request.CurrentMsg     = savedMsg;
                    ActorContext.Request.ProcessFlags   = savedFlags;
                    ActorContext.Request.CurrentRequest = savedReq;
                }

                return(InboxDirective.Default);
            }
        }