【问题标题】:Picking the right ExecutionContext选择正确的 ExecutionContext
【发布时间】:2020-08-05 06:48:25
【问题描述】:

我一直在开发一个中小型 Web 应用程序,大约有 10 个端点。它应该可以同时处理数百个并发请求。

由于我的公司政策,我不得不为我的控制器使用javax.ws.rs,所以每个控制器方法都返回一个javax.ws.rs.core.Response

每个控制器都依赖一个Service,它负责去数据库(DynamoDB,使用v2非阻塞java dynamoDb sdk),通过http从其他微服务获取数据(使用org.asynhttpclient),并创建案例代表我的响应的类,因此我的控制器可以序列化它并将其作为 javax.ws.rs.core.Response 中的主体返回。

我的应用程序中的每个组件都是异步且非阻塞的,我的服务返回Future[Either[MyAppError, CaseClassRepresentingMyResponse]]。然后,在控制器中,就在最后我等待未来的结果,并创建javax.ws.rs.core.Response

所以我的控制器看起来像这样:

class BarController(barService: BarService)(implicit ec: ExecutionContext) {

   def getFoo(userId: BigInt, fooId: String): Response = withMetrics(Bar.ServiceName, Bar.GetFoo) {
    val fooResponse = for {
      _     <- EitherT(validateUserIdAndFooId(userId, fooId))
      foo   <- EitherT(barServiceService.getFoo(userId, fooId))
    } yield foo

    Await.result(fooResponse.value, 10 seconds) match {
      case Success(Right(r)) => buildOkResponse(r)
      case Success(Left(NotFound)) => HttpResponses.notFound
      (.... a bunch of other cases ......) 
    }
  }
}

(我正在使用猫 EitherT 来处理Future[Either[E, A]]。)

我的应用程序中的每个组件都会收到一个隐含的ExecutionContext,并返回一个Future[Either[E,A]]

现在,我刚刚完成了所有的编码和测试,我需要在我的配置中提供一个正确的ExecutionContext

ExecutionContext.global 够吗?考虑到我的代码从不阻塞(因为我使用的是 DynamoDb 非阻塞 sdk 和 org.asynchttpclient),还是应该创建一个不同的 ExecutionContext?也许来自 FixedThreadPool?还是 ForkJoinPool?

【问题讨论】:

  • 我猜你现在可能只使用 global 和基准测试,如果你开始遇到问题,你可以尝试使用自定义调整它。
  • Await.result 肯定会阻止,请改用future.onComplete {...}

标签: scala asynchronous future nonblocking


【解决方案1】:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多