Instead of manually starting each stage of our GenStage pipelines, we will be supervising the upload and download pipelines under a supervision tree. Each pipeline supervisor is responsible for starting and monitoring its child processes as usual, but in this case, it will also pass the subscription options to each stage it starts.
Each stage will be registered with a name, so that we can subscribe to stages by using the name of the stage it should receive events from. Given that, we will have stages used on both upload and download pipelines, we need a way to generate unique names for a stage based on the pipeline it belongs to. The following Common.stage_name/2 function receives a GenStage module and the pipeline direction ...