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); } }