只是一个问题: 我有一个查询db的actor(假设查询需要一些时间)。 db的所有结果都返回了Future。 这基本上就是我们这样做的方式:
case class BasePay(id:String,baseSalary)
class CalcActor(db:DB) extends Actor{
override def receive: Receive = {
case BasePay(id:String,baseSalary) =>
for{
person <- db.longQueryToFindPerson(id)
calc <- db.anotherLongQueryCallCommission(person,baseSalary)
}yield Foo(person,calc)
}
如果我在期货完成之前收到很多BasePay消息会怎样? 它在排队吗?我应该注意到其他失败吗?
答案 0 :(得分:4)
如果我在期货完成之前收到很多
BasePay
消息会怎样?
许多期货将被执行,无论第一个期货何时完成。
排队了吗?
没有。让它排队的唯一方法是阻止Future
结果。由于Future
是异步调度的,因此actor可以继续处理消息。
我应该注意到其他失败吗?
这是一个广泛的问题。由于这看起来像示例代码,因此很难推测可能出现的问题。您可以通过同时分派许多查询来快速耗尽任何类型的连接池。这可以通过创建具有有限大小的ExecutionContext
来限制同时执行多少Future
个,但这不会限制演员快速接受消息。
答案 1 :(得分:1)
for comprehension使用上下文来执行代码
db.longQueryToFindPerson(id).flatMap(person =>
db.anotherLongQueryCallCommission(person,baseSalary)
.map(calc => Foo(person,calc))(aContext)//if no context will use implicit in this case the dispatcher assigned to the actor
这实际上是desugar into
implicit val context = ExecutionContext.fromExecutor(//etc)
for{
person <- db.longQueryToFindPerson(id)
calc <- db.anotherLongQueryCallCommission(person,baseSalary)
}yield Foo(person,calc)
但是未来的flatmap需要运行一个上下文,因为没有提供它将使用隐式上下文
在这种情况下将使用分配给您的actor的调度程序,因此,您的actor将与正在执行的期货竞争线程分配。因此,您的演员将增加其邮箱,直到调度员能够处理期货。
你可以指定另一个调度员来运行期货,有不同的方法。
SELECT MagazineID, DispenserID, ProductID
FROM Magazine
WHERE ProductID = (SELECT ProductID
FROM Magazine
WHERE MagazineID= 41659)
AND DispenserId = (SELECT DispenserID
FROM Magazine
WHERE MagazineID= 41659)
答案 2 :(得分:0)
如果这是默认邮箱,即你没有以某种方式指定邮箱,那么它的非阻塞和无限制,所以只要你的内存不足就可以了。 查看documentation以获取更多信息。