2016-02-19 140 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必須是可序列化和不可變的,否則它將不安全並正常工作。