Process is hangover (stuck) when call DynamicSupervisor.start_child/2 from children of the DynamicSupervisor

My case:
Application starts a DynamicSupervisor and a GenServer for adding children to DynamicSupervisor.
GenServer make children when received tasks from outside.
Each child after made by GenServer will make other children from inside process in parallel.

My issue: Children process will be hangover when calling DynamicSupervisor.start_child/2. Any one know about this issue?

This is not entirely clear. The way you describe it initially, it sounds like your hierarchy is like this:

GenServer → accepts messages and spawns tasks under the DynamicSupervisor
DynamicSupervisor → supervises a bunch of tasks running, spawned by the GenServer above

But then you are saying this:

And now it sounds that you have a multi-tier architecture? As in, the tasks under the DynamicSupervisor spawn their own tasks after that? If so, why? Why can’t all tasks be under the same DynamicSupervisor, is there any problem with that?

Thank @dimitarvp

My call flow:

GenServer → accepts messages and spawns tasks (GenServer) under the DynamicSupervisor
Tasks in the DynamicSupervisor→ spawns others tasks (GenServer). Tasks will be hangover when call DynamicSupervisor.start_child/2.

And now it sounds that you have a multi-tier architecture?

  • Just a flat architecture. All tasks are direct child of the DynamicSupervisor.

As in, the tasks under the DynamicSupervisor spawn their own tasks after that?

  • Yes, tasks will spawn new tasks.

If so, why?

  • I’m writing a prototype for my app.

Why can’t all tasks be under the same DynamicSupervisor , is there any problem with that?

  • Tasks are waiting forever in case they spawn new children from its supervisor.

I’m just try to understand how it’s happen.

What do you mean by “hangover”? :thinking:

I mean child process will be stuck (waiting forever) when call DynamicSupervier.start_child/2

Then why don’t you queue up a message for your GenServer (the one who starts the DynamicSupervisor children tasks) instead?

Hi,

As I remembered, I have experienced a case when GenServer does not send the response reply to the caller, and this process still calls some other functions, and sends the handle_call/handle_cast message to this GenServer, it jumps into loop infinity because this process of GenServer sends the message to itself which does not release yet.
Seem likes you are facing a similar case I encountered before.

1 Like

Can you show some code. A minimal reproduction of the issue?

children/parent need to get info then I have chosen easy way :sweat_smile:

For my case, GenServer in outside of DynamicSupervisor call start_child/2 in handle_info to create task then the task call start_child/2 while GenServer call init task (task is a GenServer).

Thank for your suggestion, I will try to reproduct in simple app.

From question of @TamLyNhat I think my code was deadlock.

For detail:
Children call again start_child/2 in init function while the supervisor is still waiting result from init (call from last `start_child/2’).

I will test again to verify this case.

This sounds like exactly the sort of thing that :continue and handle_continue are designed to prevent - moving the start_child call from init to handle_continue should prevent the deadlock.

5 Likes

Or, again, just have only one GenServer handle messages that are basically requests in the form of “please spawn this task with these parameters”? :person_shrugging: And have everyone post messages to it?

OP’s case seems needlessly over-complicated.

Or if the above sounds too complicated as well, then just using Oban will do.

Though if OP’s main goal is learning that I’ll retract my comments.

I honestly have no idea what you just said, sorry man. :smiley:

1 Like

Thank for your suggestion! I have tried handle_continue. It’s better than handle_info in some cases.