Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I anonymized the code:

    def start_new(name, config) do
      # Logging set up
      Supervisor.start_child(
        name,
        { HandlerModule, config }
      )
    end
    
    def replace_supervisor(name, config) do
      Supervisor.terminate_child(name, HandlerModule) # Success
      Supervisor.delete_child(name, HandlerModule)    # Failure
      start_new(name, config)
    end
     
That is exact code. Success and failure were logged. Also (from Erlang's documentation)

> one_for_one - If one child process terminates and is to be restarted, only that child process is affected. This is the default restart strategy.

In terminate child you can read that (once again Erlang).

> If the supervisor is not simple_one_for_one, Id must be the child specification identifier. The process, if any, is terminated and, [[unless it is a temporary child, the child specification is kept by the supervisor]]. The child process can later be restarted by the supervisor.

https://www.erlang.org/doc/apps/stdlib/supervisor.html#termi...

So yeah, Elixir documentation is wrong.



> Success and failure were logged.

Sorry, what happened after or during the call to delete_child/2 that caused you to consider it to have failed?

> So yeah, Elixir documentation is wrong.

I don't see what's wrong about the Elixir documentation. Walk me through it, please? Do remember that the default restart strategy for a supervisor is 'permanent', and that 'one_for_one' only ensures that the supervisor-initiated restart of one supervised child doesn't cause the supervisor to restart any other supervised children.


It was restarted by a supervisor :)

After tracing the code this is exactly what happened (in this code exactly):

    1. Terminate child X 
    2. /Supervisor restarts X/
    3. Delete child X                 {:error, :running}
    4. Supervisor.start_child Y       {:ok, PID}
    5. /X and Y are both running/

    
As for incorrectness:

> the supervisor does not restart the child in case it exits with reason :normal, :shutdown or {:shutdown, term}.

`terminate_child` is sending shutdown and yet it's being restarted.

And to emphasise on use case. The child is connection handler. Service node changed. It NEEDS to be restarted on crash, but has to be replaced during handoff.

I believe you start to get into "huh?" mode with me. I have a treasure trove of those. (Btw., in Erlang repository there's plenty of notes mentioning THIS exact behavior and if I didn't overskim - even some bugs caused by it - you can search for terminate_child.


> It NEEDS to be restarted on crash, but has to be replaced during handoff.

I question why you're handing off things between supervisors. If this is something you actually need to do, then 'delete_child/2' so the supervisor doesn't restart the child, terminate the child yourself, and re-start the child on the new supervisor.

EDIT: Actually, no, you can't 'delete_child/2'. You need to change the supervisor type from 'permanent', to the type that does exactly what you say you need. I'll leave it to you to read the docs. /EDIT

> `terminate_child` is sending shutdown and yet it's being restarted.

Here's the context for that partial quote that you pulled from [0]:

> A supervisor restarts a child process depending on its :restart configuration. For example, when :restart is set to :transient, the supervisor does not restart the child in case it exits with reason :normal, :shutdown or {:shutdown, term}.

Re-read that first sentence that you chose to not quote. Then read about the ':restart' supervisor configuration and how it describes when a supervised child is and is not restarted. [1]

> I believe you start to get into "huh?" mode with me.

Yep. Selective quoting when it's trivial for your conversation partner to find the lies by omission definitely put me into "huh?" mode with you.

[0] <https://hexdocs.pm/elixir/1.18.3/Supervisor.html#module-exit...>

[1] <https://hexdocs.pm/elixir/1.18.3/Supervisor.html#module-rest...>




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: