Funny you should say that since in Erlang-Red - since everything is an Erlang process and everything has a message queue - everything is a singleton. How does this work?
Each node becomes a separate process that lives somewhere in the Erlang machine. Each process is a equivalent to a linux process - they are completely independent and execute concurrently. Processes communicate by sending messages - Erlang messages not Node-RED messages.
Each process has a message queue which the process works off message by message. I.e. the process is an atomic process when it handles a message from the message queue. Messages are not handled concurrently by Erlang processes - their own messages of course. Processes are handling message concurrently, just their own messages are handled serially. With many 1000s of process, you have concurrency - Erlang processes are super lightweight and the intention is to spin up as many as you can.
But how does this not lead to chaos? Well that's where flow based programming is a such a good fit - because it visually organises the paths and the processes - crazy how well the two fit.
Also another thing to note. When a process sends another process a message, it can send either send it:
- async - i.e. wait for a response - message is sent to the callee process, the process sends the caller a message back, the message works its way through the caller message queue and the caller processes has its answer, or
- sync i.e. don't wait for an answer to the message - the message just lands in the message queue of the callee to be handled sometime in the future.
Erlang-Red sends node messages asynchronously between Erlang processes. Each Erlang-Red message becomes an Erlang messages (i.e. an object with msgid
as single attribute is the smallest Erlang-Red message) and is passed between Erlang processes - not nodes.
So if I want a singleton, then I create a node. Done. That node can have state and will update that state atomically per message. There is only one process per node. Nodes can create more processes, for example the exec node creates three other processes to handle command execution. But each node has one process and the process does not go down.
Erlang also encourages processes to fail. It is better to fail than to cover everything single possible edge-case is the idea in Erlang. So you end up design strategies for recovery and not for error handling.
There are a number of other features that make Erlang and the concepts of Node-RED such a good fit - immutability of data structures for example. Erlang makes many things simpler. I will hopefully have a Erlang version of @cymplecy's MQTT broker done today - that might illustrate what I mean.