我应该如何通过 DDD 将此值获取到 Akka HTTP 中的异步代码
How should I get this value through DDD to async code in Akka HTTP
我正在尝试使用域驱动设计编写一个 Akka HTTP 网络服务,但我正在努力将网络服务接收到的技术数据传递给在 Future
中执行工作的代码,即 correlationId
由客户端发送到我的网络服务。
我对 DDD 的理解是,作为实现的选择,correlationId
不应出现在域中:
package domain
trait MyRepository {
def startWork(): Future[Unit]
}
为了让我的实现代码可以使用它而不是方法的参数,我正在考虑使用像 org.slf4j.MDC
或 ThreadLocal
这样的线程本地存储。但是,我不知道这是否可行,或者对 web 服务的多次调用是否会由同一个线程处理并覆盖该值。
实现如下:
package infra
class MyRepository(implicit executor: ExecutionContextExecutor) extends domain.MyRepository {
override def startWork(): Future[Unit] = {
Future {
val correlationId = ??? // MDC.get("correlationId") ?
log(s"The correlationId is $correlationId")
}
}
}
我的网络服务中的路由:
val repo = new infra.MyRepository()
val route = path("my" / "path") {
post {
parameter('correlationId) { correlationId =>
??? // MDC.put("correlationId", correlationId) ?
onComplete(repo.startWork()) {
complete(HttpResponse(StatusCodes.OK))
}
}
}
}
我的问题是双重的:
- 我的总体设计合理且 DDD 好吗?
- 使用
org.slf4j.MDC
或 ThreadLocal
是否可行,或者是否有更好/对 Akka 更友好的实现方式?
Akka 中的本地线程(包括 MDC,尽管 Lightbend 订阅包括传播 MDC 以及消息和期货的工具)通常不是一个好主意,因为通常不能保证给定任务(Future
在这种情况下,或处理已发送消息的参与者)将在与请求任务的线程相同的线程上执行(在特定情况下,该任务正在与外部 service/DB 执行 [可能阻塞] 交互(通过使用 Future {}
暗示),您几乎不希望这种情况发生)。此外,即使该任务最终在请求该任务的同一线程上执行,也不太可能没有其他可能改变 MDC/thread-local 的任务同时执行。
我自己认为将相关 ID 作为参数传递给 startWork
没有问题:您已经通过 HTTP 端点传递它来有效地公开它。
我正在尝试使用域驱动设计编写一个 Akka HTTP 网络服务,但我正在努力将网络服务接收到的技术数据传递给在 Future
中执行工作的代码,即 correlationId
由客户端发送到我的网络服务。
我对 DDD 的理解是,作为实现的选择,correlationId
不应出现在域中:
package domain
trait MyRepository {
def startWork(): Future[Unit]
}
为了让我的实现代码可以使用它而不是方法的参数,我正在考虑使用像 org.slf4j.MDC
或 ThreadLocal
这样的线程本地存储。但是,我不知道这是否可行,或者对 web 服务的多次调用是否会由同一个线程处理并覆盖该值。
实现如下:
package infra
class MyRepository(implicit executor: ExecutionContextExecutor) extends domain.MyRepository {
override def startWork(): Future[Unit] = {
Future {
val correlationId = ??? // MDC.get("correlationId") ?
log(s"The correlationId is $correlationId")
}
}
}
我的网络服务中的路由:
val repo = new infra.MyRepository()
val route = path("my" / "path") {
post {
parameter('correlationId) { correlationId =>
??? // MDC.put("correlationId", correlationId) ?
onComplete(repo.startWork()) {
complete(HttpResponse(StatusCodes.OK))
}
}
}
}
我的问题是双重的:
- 我的总体设计合理且 DDD 好吗?
- 使用
org.slf4j.MDC
或ThreadLocal
是否可行,或者是否有更好/对 Akka 更友好的实现方式?
Akka 中的本地线程(包括 MDC,尽管 Lightbend 订阅包括传播 MDC 以及消息和期货的工具)通常不是一个好主意,因为通常不能保证给定任务(Future
在这种情况下,或处理已发送消息的参与者)将在与请求任务的线程相同的线程上执行(在特定情况下,该任务正在与外部 service/DB 执行 [可能阻塞] 交互(通过使用 Future {}
暗示),您几乎不希望这种情况发生)。此外,即使该任务最终在请求该任务的同一线程上执行,也不太可能没有其他可能改变 MDC/thread-local 的任务同时执行。
我自己认为将相关 ID 作为参数传递给 startWork
没有问题:您已经通过 HTTP 端点传递它来有效地公开它。