_Seyed

_Seyed

Hi folks,
I want to gracefully shutdown a child of a dynamic supervisor (the parent), where the child is a continuously running state machine which uses the gen_statem behavior; also, the child is trapping exits to catch signals from its parent. The parent uses the following to issue a signal to the child:
Process.exit(pid, :normal)
I expected the child to terminate; this was not the case and it continues to run code.

From reading the following links (link_1 , link_2 and link_3) It seems that Process.exit(pid, :normal) does not/should not/can not work and I should use :kill as the reason. The documentation is confusing for my case. Any help is much appreciated.

Showing Posts 1 to 10

LostKobrakai

LostKobrakai

The only way for an external process to stop a exit trapping process (ungracefully) is to use :kill reason. Otherwise the signal will be converted to a message for the exit trapping process to handle. It can decide if it shuts down or not based on the message.

_Seyed

_Seyed OP

Hello @LostKobrakai
Thank your for reaching out. You pointed to the crux of the problem. Why does the child ignore/drop the exit signal with :nromal from its parent? Do you have any suggestions for debugging the issue? For my use case, it’s better for the child process to go down gracefully.

I have not been able to reach a meaningful conclusion after reading the docs.

hst337

hst337

How do you call Process.exit(child, :normal) from parent, when parent is a dynamic supervisor?
Can you provide the code snippet?

LostKobrakai

LostKobrakai

That depends on the implementation of the child. It can do whatever it wants when handling the exit message.

_Seyed

_Seyed OP

Hi @hst337
Thanks for reaching out. This is where I send the exit signal to the child from the dynamic supervisor. It’s part of a function which issues the terminate signal to the child process and removes artifacts related to the child:

def clean_up(gv_spec)  do
# cleanup  
  case :pg.get_members(gv_spec.id) do
    [] ->
       Logger.info(%{msg: "there is no gv for given instance", id: gv_spec.id})
 
   [pid | _] ->
       Process.exit(pid, :normal)
  end
# cleanup  continued
end
_Seyed

_Seyed OP

I’m attaching a code snippet which displays how I’m trapping exits for the child, hope it helps:

@impl :gen_statem
def init(%{spec: gv_spec, config: config}) do 
# initial processing
   Process.flag(:trap_exit, true)
# create gv_spec   
   join_pg(gv_spec) 
# variable  setting : event, data, state
   {:ok, state, data, event}
end

A terminate function is also present in the child:

@impl :gen_statem
def terminate(reason, %{spec: gv_spec} = state, data) do                                                                                                                           
   leave_pg(gv_spec)
   Logger.warn(%{msg: "terminating", reason: reason, id: gv_spec.id})
end  

LostKobrakai

LostKobrakai

terminate is only called when the process actually shuts down. The exit message would be handled in a handle_event with event type :info (handle_info elsewhere).

_Seyed

_Seyed OP

Thanks for the feedback @LostKobrakai. My goal was to demonstrate that the terminate function has been implemented. As you pointed out, since the process does not terminate as expected, it doesn’t get called. To address your original point, a handle_event with event type :info is present in the code base.

LostKobrakai

LostKobrakai

Does it stop the process when it receives the exit message?

hst337

hst337

This code is called not from dynamic supervisor process, I can assure you. Perhaps this is called from dynamic supervisor module, but not process. There is actually no non-hacky way to call anything from any supervisor process (unless it is a supervisor written from scratch).


Considering the trap_exit.
Any OTP compliant process with trap_exit behaves this way:
If exit signal is received from the parent process (this can be checked in Process.get()), it is handled in a way if the child was not trapping exits. And, if the child receives exit signal from any non-parent process, it is handled as a message in handle_info (or in handle_event or state function in case of gen_statem)

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
thiagogsr
** (ArgumentError) expected :max_attempts to be a positive integer, got: {:@, [line: 10, column: 19], [{:max_attempts, [line: 10, column:...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews