Reputation: 4231
Just a question : I have an actor that queries the db (assume that queries take some time) . all results from db are returning a Future . this is basically they way we do it :
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)
}
what happens if I get a lot of BasePay messages before the futures completes ? is it queued ? are there other failures I should notice here ?
Upvotes: 0
Views: 71
Reputation: 2242
the for comprehension uses a context to execute your code
for{
person <- db.longQueryToFindPerson(id)
calc <- db.anotherLongQueryCallCommission(person,baseSalary)
}yield Foo(person,calc)
this is actually desugar into
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
but future flatmap requires a context to run, given that none is provided it will use an implicit context
in this case will be using the dispatcher assigned to your actor, therefore, your actor will be competing for threads allocation with the futures being executed. So your actor will increase its mailbox until dispatcher is able to process the futures.
you can specify another dispatcher to run the futures, there different ways.
implicit val context = ExecutionContext.fromExecutor(//etc)
for{
person <- db.longQueryToFindPerson(id)
calc <- db.anotherLongQueryCallCommission(person,baseSalary)
}yield Foo(person,calc)
Upvotes: 1
Reputation: 113
if this is the default mailbox, i.e you didn't specify a mailbox in some way then its non-blocking and unbounded so its OK as long as you don't run out of memory. check the documentation for even more info.
Upvotes: 0
Reputation: 55569
What happens if I get a lot of
BasePay
messages before the futures completes?
A lot of futures will be executed, regardless of when the first one completes.
Is it queued?
No. The only way to have it queue would be to block on the Future
result. Since the Future
is dispatched asynchronously, the actor is able to continue processing messages.
Are there other failures I should notice here?
This is a broad question. Since that looks like example code, it is difficult to speculate what could go wrong. You could quickly exhaust any sort of connection pool by dispatching many queries at the same time. That can be limited by creating an ExecutionContext
with a limited size to throttle how many of the Future
s are executed at the same time, but that would not limit the actor from accepting the messages rapidly.
Upvotes: 4