传递上下文信息

时间:2016-02-19 17:00:31

标签: c# akka akka.net

我们正在将akka.net演员添加到遗留系统的一部分。

基本思想是来自外部系统的消息,它被传递给由akka.net actor管理的逻辑,然后与遗留组件进行通信,这些组件执行将数据保存到数据库等事情。

遗留代码依赖于在CallContext中设置userId的事实,然后它可以在进行数据库写入之前检索(存储诸如" CreatedBy"" LastModifiedBy" )。很明显,一旦消息通过actor系统传递,CallContext将不可用。

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

在akka.net中是否存在上下文包装器/信封的概念,或者是我唯一的选择,使上下文信息的传递成为消息的明确部分?

2 个答案:

答案 0 :(得分:4)

由于您的消息可能跨越actor系统边界,因此这里的最佳选择似乎是将CallContext和消息包装起来,并在消息到达时加载到actor的某个字段。以下是使用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))
}

这样,当消息命中actor的receive方法时,将加载调用上下文。请记住,为此,CallContext必须是可序列化且不可变的,否则它将不安全且无法正常工作。

答案 1 :(得分:1)

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

但是,如果您使用Ask使用ActorSystem,则执行文本将由TPL捕获并在任务的继续中恢复。