1
votes

I have a Master actor which creates Worker actors using router. Each Worker actor performs several HTTP connections.

And from several sources I learnt that if actor doing some blocking operation, then it's better to wrap blocking operation into this construct:

val resFut = future {
  blocking {
    executeQuery()
  }
}

resFut pipeTo sender

But then I read official topic about handling blocking operations in Akka, and I was surprised that topic suggest just to use router for blocking operations (as alternative to Futures):

Do the blocking call within an actor (or a set of actors managed by a router), making sure to configure a thread pool which is either dedicated for this purpose or sufficiently sized.

So my question is: should I use following construct in my Worker actor even if it backed by router?

future {
      blocking {
        executeQuery()
      }
}

Or just configuring and using another dispatcher for router will help me to achieve same benefits?

1

1 Answers

2
votes

You can do either. The doc you reference basically says ~ either use a router with worker actors, single actor or futures.

The whole idea is that a thread might block and you want to manage it properly - you should have an upper limit on the number of threads that block. This can be achieved either with a router by controlling number of routees, or with futures by manually controlling number of concurrent runs or using a bounded thread pool.

In either case, if you use an actor that blocks use its parent (controller) to communicate with the client. This way if the worker actor dies by exception or timeout your client will still receive response. Thus, controller should never crash and be responsive to multi-client requests.

There is no need to have both actor-per-request pattern and future wrapping the blocking code unless you find it convenient (using pipeTo with timeout for example).

To control number of actors in the router there are 2 related levels of config. Lower level config is your Dispatcher config that defines number of threads to use. On top of it is Router config that uses nrOfInstances to control how many routees can exist - upper limit. You should size your thread pool in the dispatcher to be somewhere around NRouters * NRoutees for blocking operations.