3

I have been reading the docs but it is not very clear to me if there will be only one Dispatcher associated to every actor or if there is only one. Lets say I have actor SendSmsActor and actor UpdateSmsActor, will they both use the default dispatcher? or each Actor its gonna get its own default dispatcher instance? Also it is not very clear for me if I am having 500 incoming requests (as a part of a batch process), and my parallelism-max is set to 300, will these 300 threads be split between SendSmsActor and UpdateSmsActor?

Diego Ramos
  • 989
  • 4
  • 16
  • 35
  • yes both will use the default dispatcher unless you specify it explicitly, you can say there will be 300 threads but that will not work in parallel because parallelism depends on the number of core you have it's more of the context switching. – Raman Mishra Jun 13 '19 at 05:25

2 Answers2

1

By default, Akka uses the default dispatcher for executing the actors over the threads. A dispatcher is common for all the actors within the Actor System. Akka also provides the option to write custom dispatcher. You can specify the type of executor within the dispatcher.

The threads will not be split between the actors. Whatever free thread is available within the dispatcher will be used to execute to the actor

The default dispatcher configuration is:

default-dispatcher {
type = "Dispatcher"
executor = "fork-join-executor"

fork-join-executor {
    parallelism-min = 8
    parallelism-factor = 3.0
    parallelism-max = 64
}

thread-pool-executor {
    keep-alive-time = 60s
    core-pool-size-min = 8
    core-pool-size-factor = 3.0
    core-pool-size-max = 64
    max-pool-size-min = 8
    max-pool-size-factor  = 3.0
    max-pool-size-max = 64
    task-queue-size = -1
    task-queue-type = "linked"

    allow-core-timeout = on
}

}

Reference: What are the default Akka dispatcher configuration values?

bumblebee
  • 1,811
  • 12
  • 19
1

Both of your actors will be executed on the default dispatcher unless you explicitly assign an alternative dispatcher for the actor instance, either configuratively or programmatically.

The default fork-join dispatcher will load balance your actors across the threads. However, the throughput option will determine how many messages per actor should be processed before switching to another actor.

Depending on your workload, 300 dispatcher threads may or may not be optimal. If your actors are completely non-blocking, then you probably want to have roughly 1 thread per CPU core as a starting point and then do some benchmarking to fine-tune that number. Otherwise, you will be wasting CPU cycles doing unnecessary context switching. If your actors block, then you probably want to provide a separate dispatcher and configure your blocking actors to use that one instead. See Blocking Needs Careful Management.

Eric
  • 906
  • 7
  • 13
  • Hi Eric, thanks for the reply, I got some SendNotificationActor that is consuming a REST API (hence being a blocking operation), I am thinking on creating a new dispatcher for this, does it have to be a thread-pool-executor with a fixed pool size ? Or can it be a fork-join-executor instead? thanks for the reply – Diego Ramos Jun 14 '19 at 04:20
  • @DiegoRamos, you should confirm whether your http client is blocking or non-blocking. If non-blocking, just use the default dispatcher. If blocking, you probably want to use a thread pool executor with a fixed size to limit the number of threads that get started. – Eric Jun 15 '19 at 20:46
  • it is blocking, why should we used thread-pool-executor instead fork-join? – Diego Ramos Jun 16 '19 at 22:45
  • The thread pool executor will limit the number of threads spawned so it's good to use for I/O-bound tasks with arbitrarily long task latencies. The fork join pool is mainly used for CPU-bound tasks. – Eric Jun 16 '19 at 22:57