我正在开发一个移动应用程序的后端,该应用程序当前在 Play 2.1.1 上运行。作为处理某些请求的一部分,我们会发送推送通知。发送推送通知的下游请求应该完全异步,并且与移动客户端的原始请求响应分离。
我想访问Http.Context.current()
发送下游请求以访问我们在请求标头中传递的一些跟踪信息。
最初,代码看起来像这样,遵循中的建议玩!文档 http://www.playframework.com/documentation/2.1.0/JavaAkka:
PushNotificationRunnable sendNotificationTask = new ...
Akka.system().scheduler().scheduleOnce(Duration.apply(0, TimeUnit.MICROSECONDS),
sendNotificationTask, Akka.system().dispatcher());
探索play.libs.Akka
helper 引导我找到 future 方法,该方法接受一个可调用对象并返回一个 Promise。这个承诺允许我链接更多代码。在这里我链接了一个Callback
which 可以访问 Http.Context.current()感谢设置代码Play's PromiseActor class https://github.com/playframework/playframework/blob/2.1.1/framework/src/play/src/main/java/play/libs/F.java#L412。这允许我在任务完成时记录一行,包括跟踪 ID,但在任务期间我的日志行仍然无法访问跟踪信息。
PushNotificationCallable sendNotificationTask = new ...
Akka.future(sendNotificationTask).onRedeem(new F.Callback<Void>() {
@Override
public void invoke(Void aVoid) throws Throwable {
Logger.info("Completed sendNotificationTask from the service");
}
});
以下是一些简短的应用程序日志,用于显示我当前所在的位置以及缺少的内容,跟踪 ID 在第五列中:
2013-07-26 11:31:06,885 DEBUG play-akka.actor.default-dispatcher-10 -2454018518484259555 [application] : Processing request for mobile app
2013-07-26 11:31:06,907 DEBUG play-akka.actor.default-dispatcher-10 -2454018518484259555 [application] : About to schedule push notification message send
2013-07-26 11:31:06,907 INFO application-akka.actor.default-dispatcher-8 n/a [services.PushMessageSenderTask] : Sending message in akka background task
2013-07-26 11:31:06,924 INFO application-akka.actor.default-dispatcher-8 n/a [services.PushMessageSenderTask] : Sent message in akka background task
2013-07-26 11:31:06,925 INFO play-akka.actor.default-dispatcher-16 -2454018518484259555 [application] : Completed sendNotificationTask
这些字段是日期、时间、级别、线程和跟踪 ID。使用此 logback 配置(如果有帮助):
%d{ISO8601} %-5level %thread %traceId [%logger] : %msg%n
可以看到,第3行和第4行来自Akka线程,无权访问TraceId,而是打印n/a
。第 1 行和第 2 行位于初始请求处理线程上,并且具有访问权限。最后,第 5 行位于不同的请求处理线程上并且也具有访问权限。
是否有某种不同的方式可以安排任务,使其能够访问 Http.Context.request(),但仍会在浏览器的请求响应循环“外部”运行它?