如何在Akka中保留请求上下文数据

Dre*_*ter 9 asynchronous scala akka playframework

作为Java EE开发人员,我使用了MDC(映射诊断上下文)方法来处理与请求相关的上下文数据,例如,用于跟踪请求中的许多潜在日志事件的唯一请求令牌.该请求的有效期.

鉴于它依赖于ThreadLocal,很明显这种方法在使用异步技术时会崩溃.

我还处于学习Scala的早期阶段,与此问题更相关的是Akka.我已经阅读了很多论坛帖子,证实了Akka和MDC的不兼容性,但尚未发现一种以某种方式模仿MDC方法的一致策略.

是否最好只是明确地传递这种数据作为在演员之间发送的消息的一部分?它有点脏,但同时兼容无法轻松扩展的能力.

除了直接通过消息之外,还有其他方法可以将上下文传递给Actor吗?此外,在使用Play 2.0 Async块时,有没有人遇到过同样的挑战?

ido*_*nie 1

我认为您可以使用ThreadLocal在静态上下文中声明的 -s ,与此代码中的执行器隐式参数相同:

implicit val executor = context.dispatcher
val f = Future[Boolean] {
  someTask()
} andThen { 
  case err if err.isLeft => log.error("Some error: " + err.left.get); false
  case ok if ok.isRight => log.info("Good work: " + ok.right.get); true
}
Run Code Online (Sandbox Code Playgroud)

每次 future 向调度程序提交任务时,都会将一个线程安全上下文对象从一个线程复制到另一个线程中。因此,您需要一个自定义调度程序 - 通过任何方式读取ThreadLocal,将其存储在执行程序(调度程序)内部的某个位置,然后提交首先写入的任务ThreadLocal