> Message-passing interfaces are generally difficult to discover and to debug, and require a lot of careful documentation, logging & instrumentation.
You just use the "most common structures". For example, Elixir has the Agent module, which encapsulates state, but lets whatever you're using interact with the state via lambdas (or passed functions).
Another common structure is the state machine. I was somewhat displeased with the complexity of gen_statem, so I wrote my own! It's about 50 lines of code, and can have plugins to do facilities like logging and debugging via a plugin-able interface.
Ultimately the real win with message-passing is not having to write spinlocks, semaphores, or mutexes.
You just use the "most common structures". For example, Elixir has the Agent module, which encapsulates state, but lets whatever you're using interact with the state via lambdas (or passed functions).
Another common structure is the state machine. I was somewhat displeased with the complexity of gen_statem, so I wrote my own! It's about 50 lines of code, and can have plugins to do facilities like logging and debugging via a plugin-able interface.
Ultimately the real win with message-passing is not having to write spinlocks, semaphores, or mutexes.