how to bind each actor in a pool to a thread

113 views
Skip to first unread message

mc

unread,
Jul 27, 2017, 2:07:30 PM7/27/17
to Akka User List
Hello,
I have an Akka app that is interfacing with machine learning algorithms written in Python.
I'd like to guarantee that each of the Python worker actors is always executed using the same thread:
PythonWorker1 -> thread1
PythonWorker2 -> thread2
...

Could someone provide an example on how to achieve that?
Thanks,

M

Rafał Sumisławski

unread,
Jul 27, 2017, 2:17:12 PM7/27/17
to Akka User List
Hi
A PinnedDispatcher may be what your looking for. It creates a dedicated thread for each actor.

It's documented (with an example) here: http://doc.akka.io/docs/akka/current/scala/dispatchers.html#types-of-dispatchers

Best Regards,
Rafał

mc

unread,
Jul 31, 2017, 6:26:34 PM7/31/17
to Akka User List
Hello,

I tried to use PinnedDispatcher using the following configuration (in application.conf):

app {
    pinnedDispatcher {
        type = "PinnedDispatcher"
        executor = "thread-pool-executor"
        thread-pool-executor.allow-core-timeout = off
        thread-pool-executor {
            core-pool-size-min = 2
            core-pool-size-factor = 2.0
            core-pool-size-max = 4
        }
        throughput = 1
    }
}

akka.actor.deployment {
        /master/worker {
            dispatcher = app.pinnedDispatcher
            router = round-robin-pool
        }
}

This is my code for creating worker pool (inside MyMaster actor called "master"):
  private lazy val worker = context.actorOf(FromConfig.props(Props[MyWorker]), "worker")

Worker actors are receiving messages but it looks like actors created on one thread are later executed on another thread.
Is my configuration incorrect? I thought that using pinned dispatcher would guarantee that an actor created on a thread would later be always called from that same thread.
I'd appreciate any help with this problem.
Thanks,

M

Rafał Sumisławski

unread,
Aug 1, 2017, 3:49:00 PM8/1/17
to Akka User List
I'm not experienced with configuring routers from config, since I prefer using code, but as far as I understand you did set a dispatcher for the /master/worker - the router, not for it's routees - the actual worker actors. If you print the thread name in constructor an in receive of workers you should see that your using default-dispatcher.

Something like this may be closer to what you're trying to achieve:
akka.actor.deployment {
    /master/worker {
        pool-dispatcher = {

            type = "PinnedDispatcher"
            executor = "thread-pool-executor"
            thread-pool-executor.allow-core-timeout = off
            throughput = 1
        }
        router = round-robin-pool
    }
}

BTW AFAIK you shouldn't/don't have to configure thread pool size for a pinned dispatcher. It's creating a separate single-thread pool for each actor.

mc

unread,
Aug 1, 2017, 5:27:56 PM8/1/17
to Akka User List
Hello,

Thank you for your help. After reading your comment ("the router, not for it's routees") I remembered about actor groups (as opposed to pools).
I defined a common pinned dispatcher (in application.conf, directly under "akka" element):


    pinnedDispatcher {
        type = "PinnedDispatcher"
        executor = "thread-pool-executor"
        thread-pool-executor.allow-core-timeout = off
    }

Then created worker actors first:

  private lazy val workers = for (i <- 0 until MyWorkerCount) yield {
    context.actorOf(Props[MyWorker].withDispatcher("pinnedDispatcher"), "myWorker" + i) //actor names need to be unique
  }

And then created round robin actor group:

  private lazy val workerGroup = context.actorOf(RoundRobinGroup(workers.map(_.path.toString)).props(), "workerGroup")

Now each worker actor in the group is running on a separate thread, and always on the same one.
Thanks,

M
Reply all
Reply to author
Forward
0 new messages