How to regulate the speed between actors in java?

65 Views Asked by At

When there are three actors in a sequence - actor1 -> actor2 -> actor3 - and actor3 has significantly slower processing speed, it causes actor1 to rapidly send messages, leading to a backlog of messages in actor3. Consequently, the program's execution time gradually slows down when time goes on, and it seems like there's heavy garbage collection (GC) usage. In such a scenario, how can this be addressed using actor in java?

Any idea or keyword will be appreciated.

1

There are 1 best solutions below

0
Levi Ramsey On

One useful technique is for actor3 to signal demand for messages from actor2. For instance, when actor3 starts, it can send a message to actor2 saying, "I can handle 10 messages". When it receives the first message from actor2, it schedules (or perhaps sends) a message to itself and records that, when it comes time to update demand, it can demand 1 more message. The message to itself will go into the mailbox with the messages from actor2. When that message to itself is received, it checks how many more messages it can demand and sends another message to actor2 to give it permission to send that many more messages.

Actor2 basically tracks how many messages it has permission to send to actor3. If it wants to send a message to actor3, it has to buffer that message until it gets permission. Actor2 likewise sends demand/permission-to-send messages to actor1 (and it likely would not signal more demand when there are any messages buffered for sending to actor3).

This is basically the backpressure protocol for Akka Streams. Within a JVM, where there's a stronger delivery guarantee, this is basically sufficient: in the distributed case, one can add time limits to demand/permission-to-send and so forth.

Note that since Akka Streams is an extremely "battle-tested" implementation of this pattern, it may be worth considering moving the logic of the actors into stream stages: the stream DSLs can do many things, and even more can be expressed as a custom GraphStage (it's even possible to get an ActorRef for the stage and have the stage process actor messages "out-of-band", though with this great power comes great responsibility).