Discovering a task supervisor local to my supervision tree

I was writing a GenServer and quickly discovered the need to generate tasks within this GenServer. This GenServer can not have a globally unique name (as I require many instances of it. I decided to keep the current module structure, changing the GenServer to a Supervisor and spawning my original GenServer as a child of this supervisor (with the Supervisor having public functions that call the child GenServer). Ideally, my supervision tree would look something like this

             /  \
            /    \
   MyGenServer   MyTaskSupervisor

Also, ideally, I would spawn my tasks within MyTaskSupervisor. However, the obvious question arises: how does MyGenServer discover this task supervisor? In other projects, I’ve given this task supervisor a globally unique name, but I can’t do that here.

Looking into the problem, I’ve seen many suggestions to use a Registry, but those require globally unique names. In order to have a registry for my task supervisors, I’d have to spawn the Registry in my root supervisor to ensure all of my processes can find it. It would be a lot nicer if I could somehow register the task supervisor in the context MyServerSupervisor. Is there a way to achieve what I want, or is the closest analog the solution I just described?


Question about naming:

How do you tell these apart? That’s where a Registry would usually come in handy.

For instance, imagine that each instance can be identified by an Erlang term that we’ll call id. Could be a database ID, could be a UUID, could be an ARN, whatever.

Start a single top-level Registry instance, we’ll name it MyServerRegistry for concreteness.

Then instances of MyServerSupervisor would name themselves like:

{:via, Registry, {MyServerRegistry, id}}

While instances of MyGenServer and MyTaskSupervisor could be named like:

{:via, Registry, {MyServerRegistry, id, :server}}
# vs
{:via, Registry, {MyServerRegistry, id, :task_supervisor}}

How do you tell these apart? That’s where a Registry would usually come in handy.

In those cases I was just going to use an atom for a name (they don’t need to be dynamically generated and there’s not many of them).

That does seem like a sensible strategy though.