Akka Ask 是否阻塞当前线程 [英] Is Akka Ask Blocking on the Current Thread

查看:31
本文介绍了Akka Ask 是否阻塞当前线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个场景,我必须通过他的 id 获取用户的详细信息.这是一个进入我的 HTTP 处理程序层的 HTTP 请求,我利用从请求中获得的 id,向参与者发送一条消息,然后参与者与数据库服务对话以获取用户.

I have a scenario where I have to fetch the details of a user by his id. It is a HTTP request that comes in and in my HTTP handler layer, I make use of the id that I get from the request, send a message to the actor which then talks to the database service to fetch the user.

现在由于这是一个 HTTP 请求,我需要通过发回响应来满足请求.于是想到了使用Akka ask模式,但心里有以下几个问题:

Now since this is a HTTP request, I need to satisfy the request by sending a response back. So I thought of using the Akka ask pattern, but I have the following questions in mind:

  1. 这会阻塞我当前的线程吗?

  1. Is this going to block on my current thread?

在我的案例中,这里使用询问模式来获取用户是一种可扩展的解决方案吗?我的意思是,在任何给定的时间点,我都可能有数百到一百万用户呼叫此端点.使用询问模式获取用户是否是个好主意?

Is using ask pattern here to fetch a user in my case a scalable solution? I mean, I could have a few hundreds to a million users calling this end point at any given point in time. Is this a good idea to use the ask pattern to fetch a user?

在代码中,它在我的 HTTP 控制器中看起来像这样

In code, it looks like this in my HTTP controller

val result: Future[Any] = userActor ? FetchUser(id)

在我的演员中,我会做以下事情:

In my actor, I would do the following:

case fetchUser: FetchUser => sender ! myService.getUser(fetchUser.id)

推荐答案

按照您提出问题的顺序回答问题:

Answering your questions in the same order you posed them:

  1. 否,使用 ? 不会阻塞当前线程.它立即返回一个 Future.但是,Future 中的结果可能无法立即获得.
  2. 如果您需要解决方案具有可扩展性",并且您的服务能够进行多个并发查询,那么您可能需要使用 Actors 这样你就可以同时服务多个 ? ,或者只见下面的 Futures,可扩展, 解决方案.
  1. No, using the ? does not block the current thread. It returns a Future immediately. However, the result within the Future may not be available immediately.
  2. If you need the solution to be "scalable", and your service is capable of multiple concurrent queries, then you may need to use a pool of Actors so you can serve multiple ? at once, or see below for a Futures only, scalable, solution.

独家期货

如果您的 Actors 没有缓存任何中间值,那么您可以直接使用 Futures 并避免 Actors 的繁琐(例如 Props、actorOf、receive、?、...):

If your Actors are not caching any intermediate values then you can just use Futures directly and avoid the rigmarole of Actors (e.g. Props, actorOf, receive, ?, ...):

import java.util.concurrent.Executors

import scala.concurrent.{ExecutionContext,Future}    

object ServicePool {      

  private val myService = ???

  val maxQueries = 11 //should come from a configuration file instead

  private val queryExecutionPool = 
    ExecutionContext.fromExecutor(Executors.newFixedThreadPool(maxQueries))

  type ID = ???

  /**Will only hit the DB with maxQueries at once.*/
  def queryService(id : ID) = 
    Future { myService getUser id }(queryExecutionPool)

}//end object ServiceQuery

您现在可以随心所欲地调用 ServicePool.queryService,但该服务一次不会被超过 maxQueries 命中,并且没有 Actor:

You can now call ServicePool.queryService as often as you want but the service will not be hit with more than maxQueries at a single time, and no Actors:

val alotOfIDs : Seq[ID] = (1 to 1000000) map { i => ID(i)}

val results = alotOfIDs map ServicePool.queryService

这篇关于Akka Ask 是否阻塞当前线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆