When does a genserver process die

I am creating multiple Genservers and have set an exit condition on them. I create each Genserver with a process id and then

def handle_cast({:receive_message, message}, zero_counter_gossip_true) do
  // counter increased for the number of times this message has been called for this particular process
  if new_message_counter < 9 do
    GenServer.cast(self(), {:send_periodic_message})
    Process.exit(self(), :normal)

def handle_cast({:send_periodic_message}, zero_counter_gossip_true) do 
    // The node to send is chosen from a list of nodes
    GenServer.cast(node_to_send,{:receive_message, "ChitChat"}
    GenServer.cast(self(), {:send_periodic_message})                             
    // some code below

I expect the Genserver to exit only when the counter reaches 9 but I can see a lot of Genservers exiting with the message.

The node transmitting message is: [#PID<0.77.0>, 1]

where the first part is the PID and second the counter on number of times the receive_message has been called. Am I missing something here. Is the process timing out ? Any help would be appreciated TIA.

Can you provide a complete example?

How complete is the code? Your first clause of handle_cast/2 should return {:noreply, zero_counter_gossip_true}. Btw wouldn’t it be better to wrap that state in a struct even if it only has one field? It would make it clearer what you are passing around in all the callbacks.

1 Like


Hey, thanks for looking into it. I have attached a pastebin of the code below if you wanna see that. Do you mean to say that I should do in the if part of the receive message. I am returning something but that is common for both if and else and after the loop.

Instead of

GenServer.start_link(__MODULE__, zero_counter_gossiping_neighbors)


GenServer.start_link(__MODULE__, zero_counter_gossiping_neighbors, debug: [:trace])

to get some more debugging output.

Thanks for letting me know about that. I did not get anything other than the normal inspect statements i was printing.

I am thanktul to everyone who has tried to help. I would like to clarify one of my statement though.
When I say the process exits, I am not sure if it has exited in the backend. I just know that the command prompt returned back to me without the process reaching the 9 counter value. I know the counter value since I put an inspect statement over there.

Some questions:

  • Do you see any output from the system that a process has died or is it quiet?
  • How do you mean “return to the command prompt”? How have you started the system and how are you running it? I mean do you have a function you call to send a cast message to the server?
  • If your system is running asynchronously then you may very well return to the command prompt while the system is still running. Doing a GenServer.cast is asynchronous and returns immediately, that is why I am asking.

Another way of terminating the genserver is for handle_cast to return {:stop, reason, state} where reason could be :normal in your case.

There is a way to see which processes are running in the system and that is to call the erlang function :c.i() which lists all the processes currently running. I don’t know if there is an equivalent helper function in the elixir shell.

1 Like

The equivalent is… the same

iex> :c.i()

Thanks for the tip :slight_smile:

1 Like

Hey, I could find that the process had gone in the backgroudn(async) and used these techniques to see. Thanks for the help. Please close the issue.

You are the OP, so You can close the issue :slight_smile: Just select the appropriate answer and set it to solution.

1 Like