Reentrancy

Overview

In the actor model, an actor processes messages one at a time, maintaining its own private state. Traditionally, this means an actor is non-reentrant: while handling a message, it will not process another until it finishes.

Actor reentrancy relaxes this rule. A reentrant actor is allowed to process other messages while it is awaiting the result of an asynchronous operation. This can significantly improve responsiveness and throughput, but it also introduces new risks.

In short:

Reentrancy trades strict safety for better concurrency.

Importance

Modern actor systems often rely heavily on async I/O: database calls, HTTP requests, timers, and remote actor calls. If actors were strictly non-reentrant, they would sit idle during every await, wasting resources.

Reentrancy allows:

  • Better utilisation of threads

  • Lower latency under load

  • Higher overall throughput

  • Avoid deadlocks in call cycles but allows actor state to change between request and response handling

This is especially attractive in high-scale, distributed systems.

Reentrancy works well when:

  • Message handlers are stateless or idempotent

  • State is updated before awaiting

  • Actors act mainly as coordinators

  • You can tolerate relaxed ordering guarantees

It is often safe for:

  • Read-heavy workloads

  • Caching actors

  • Request routing and orchestration

Common Pitfalls

Reentrancy often causes bugs that are:

  • Hard to reproduce

  • Sensitive to timing

  • Mistaken for “distributed system issues”

Typical mistakes include:

  • Assuming state is unchanged after an await

  • Updating shared state in multiple message handlers

  • Performing multi-step workflows without protection

These bugs are logical, not technical — the system is doing exactly what it was told.

Get Started

Reentrancy is enabled for actor during their creation using the WithReentrancy SpawnOption.

Once the reentrancy option is properly configured, the feature can be used through the following methods available on the ReceiveContext:

  • Request: A non-blocking counterpart of Ask. This method can only be used locally or within a single-node actor system.

  • RequestName: Similar to Request, but location-transparent.

More information can be found on the godocs of the methods and options of the reentrancy capability. An working example can be found here.

Last updated