Based on my GenStage experiments and reading the ConsumerSupervisor documentation here are my thoughts:
-
ConsumerSupervisor is a Supervisor process which creates a child process for each event that it receives. In general Supervisors are designed to be as simple as possible so that they can focus on one thing: “supervising child processes” (while not taking on any additional responsibility which may cause them to crash) - this one just happens to dynamically create children for any events received. By this nature the ConsumerSupervisor can only really be a Consumer in a GenStage scenario as a supervisor typically doesn’t collect and manage results from its children.
-
Your particular
[A] -> [B(1, 2, 3, 4, 5, ...)] -> [C]
scenario could be realized with C as a Producer (if there is a (producer-) consumer D). Essentially the children of the ConsumerSupervisor would simply deliver their result to C viaGenStage.cast/2
orGenStage.call/3
- i.e. flow to C would be entirely governed by the:min_demand
,:max_demand
settings on B, the ConsumerProducer. -
The documentation of
init
is strange to say the least. There is aConsumerSupervisor.init/1
callback that is analogous toSupervisor.init/1
- so I would expectConsumerSupervisor.init/1
function to be analogous toSupervisor.init/2
. The text of theConsumerSupervisor.init/2
function seems very similar to the text of the Genstage.init/2 callback - so I suspect a copy/paste error. TheConsumerSupervisor.init/1
function code simply prepares a tuple containing the supervisor flags and child specifications.