2016-02-19 99 views
1

我们在加入akka.net演员遗留系统的一部分的过程。传递上下文信息

其基本思想是,一条消息从外部系统进入,它被交给一个由akka.net演员管理的逻辑,然后与传统组件进行对话,这些组件将数据保存到数据库中。

传统代码依赖于在CallContext中设置userId,然后在数据库写入之前可以检索(存储诸如“CreatedBy”和“LastModifiedBy”之类的东西)的事实。看起来很清楚,一旦消息传递给actor系统,CallContext就不可用。

这似乎将是一个常见的问题/需求,但我一直无法找到通过谷歌或者这个问题通过阿卡/ akka.net讨论组期待。

是否有akka.net上下文包装/信封的概念,或者是我做的上下文信息传递的唯一选项消息的明确的一部分吗?

回答

1

Akka.NET目前不是很ExecutionContext友好。如果AppDomain完全信任,ThreadPoolDispatcher正在使用ThreadPool.UnsafeQueueUserWorkItem,因此CallContext不会流过actor。

但是,如果你消耗与询问ActorSystem,在执行上下文将由TPL捕获并在任务的持续恢复。

4

由于您的消息可跨演员系统边界可能通过,最好选择在这里似乎被包裹CallContext中和消息传递,并加载在消息到达演员的领域之一。下面是使用AroundReceive方法示例代码:

public struct Wrapper { 
    public readonly CallContext CallContext; 
    public readonly object Message; 
    ... 
} 

public abstract class ContextualActor : ReceiveActor { 
    protected CallContext CallContext; 
    protected override bool AroundReceive(Receive receive, object message) { 
     if (message is Wrapper) { 
      var wrapped = (Wrapper)message; 
      CallContext = wrapped.CallContext; 
      return base.AroundReceive(receive, wrapped.Message); 
     } 
     else return base.AroundReceive(receive, message); 
    } 

    public void Send(IActorRef aref, object message) => 
     aref.Tell(new Wrapper(CallContext, message)) 
} 

这样,呼叫内容将被加载,当消息到达一个演员的接收方法。请记住,为此,CallContext必须是可序列化和不可变的,否则它将不安全并正常工作。