Beispiel #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);
            }
        }
 public ActorRequestContext SetCurrentRequest(ActorRequest currentRequest) =>
 new ActorRequestContext(
     System,
     Self,
     Sender,
     Parent,
     CurrentMsg,
     currentRequest,
     ProcessFlags,
     Ops
     );
 internal static RemoteMessageDTO CreateRequest(ActorRequest req, ProcessId to, ProcessId sender, Option <SessionId> sessionId) =>
 new RemoteMessageDTO
 {
     Type        = (int)Message.Type.User,
     Tag         = (int)Message.TagSpec.UserAsk,
     Child       = null,
     Exception   = null,
     To          = to.ToString(),
     RequestId   = req.RequestId,
     MessageId   = Guid.NewGuid(),
     Sender      = sender.ToString(),
     ReplyTo     = req.ReplyTo.ToString(),
     ContentType = req.Message.GetType().AssemblyQualifiedName,
     Content     = JsonConvert.SerializeObject(req.Message, ActorSystemConfig.Default.JsonSerializerSettings),
     SessionId   = sessionId.Map(s => s.Value).IfNoneUnsafe(() => null)
 };
 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;
 }
Beispiel #5
0
 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));
Beispiel #6
0
 public InboxDirective ProcessAsk(ActorRequest request) => InboxDirective.Default;
Beispiel #7
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);
            }
        }