Is it possible to spawn and link to multiple processes atomically?

According to the docs spawn_link is atomic between the caller and the spawned process. Is there any way to atomically spawn and link to other processes that are not the caller, such as a list of other processes? Or is the only available option to call link/1 on each pid right as the process starts?

If you are are trying to avoid using a gen_{server,statem} (do your link/1’ing in init/1) then have a look at proc_lib though your colleagues might come for you in your sleep for making things potentially more confusing unnecessarily.

Remember, code safely…assume the person that inherits your codebase is a crazed axe ‘enthusiast’ who knows where you live. :slight_smile:

1 Like

Maybe I am missing something in proc_lib. From what I can read, all of those functions still only mention the ability to atomically link to a single process while spawning. My use-case is similar to spawn_link or proc_lib:spawn_link but the difference is that I need to atomically link to not just the caller but an arbitrary amount of processes (3 more than the caller for now). I also do not want to trigger an exit signal from being sent if a process later in the sequence of link calls doesn’t exist, the standard noproc exception that link raises is desirable.

So for example:

% Extra processes that are the caller that require links
Pids = [P1, P2, P3],
spawn_link(fun() ->
  % P1 link succeeds
  link(P1),
   % P2 no longer exists, triggering a noproc exception.
   % Have to manually unwind stack of successfully linked
   % pids to perform unlinking.
  link(P2),
  link(P3)
end ).

A different way of phrasing the question is: is there a built in way to atomically link to multiple processes while spawning, or is a manual process needed to accomplish the same thing and perform an unlinking step for processes early in the list of pids, if one of the later ones fails to link?

This is to avoid propagating exit signals to those successfully linked pids and raise an error at the call site.

is there a built in way to atomically link to multiple processes while spawning

No.

This is to avoid propagating exit signals to those successfully linked pids and raise an error at the call site.

This I understand, as in what you are trying, not sure of the why. As in I am trying to conjure up a situation that this pattern fits, but struggling so mostly curious about the use case here.

Depending on where those pids came from, this smells awfully close to an one_for_all supervisor running with any_significant plus all its children marked significant.

Could you reorientate towards this and have those processes originate under their own grouped supervisor?

…or is a manual process needed to accomplish the same thing

If not I think your only option is this manual process, just remember to peek into the message queue after untrapping to catch if something slipped in between the cracks.

A different way of phrasing the question is: …

Might be worth reasoning what is the material impact is of not having such a multi-link/2 operator. For example, if after making such a multi-link/2 call, the caller sees ok but immediately afterwards one of those pids dies.

Thanks for confirming there is not an available method.

What U want to do seems tangential to supervision. Three processes need to perform cleanup, and these three processes have crashed in various scenarios in the past. I wanted to make this more defensive incase one of the three died before linking by relying on something built in. I will explore more elegant ways.

Thanks!