Supervised GenServer functions: How to keep them running even after restart?

defmodule Sandbox do
   use GenServer

  def start_link() do
    GenServer.start_link(__MODULE__, [], name: __MODULE__)
  end

  @impl true

  def init(_) do
    :observer.start
    main()
    {:ok, :running}
  end

  def main do
    IO.puts("Hello World!")
  end

This is part of the application Foo. Sandbox is a supervised GenServer which executes the main function when Foo is started and whenever Sandbox crashes and is restarted by the Supervisor. :observer displays it as Elixir.Sandbox under its Applications tab.

However, if main is changed as follows-

  def main do
    IO.puts("Hello World!")
    main()
  end

:observer no longer shows the app nor the Elixir.Sandbox GenServer process which seems to indicate that either the Supervisor or the GenServer didn’t start. (Please correct me if this is not actually the case.)

The goal: To keep mainrunning perpetually even after its restarted by the Supervisor. What’s the best way to accomplish this?

Edit: use GenServer added

Learning about processes is the heart of the BEAM. It is also why the BEAM is attractive.

But it is hard and I advise You to watch those free lessons here before writing your own gen_server.

https://www.cs.kent.ac.uk/ErlangMasterClasses/

In particular, classes 2 and 3. Because class 1 is more about FP.

Your code needs corrections…

  1. You did not put use GenServer
  2. You should not start the observer from a server, but from the console
  3. It is not the way You make a recurrent call to a function, You have no control over the loop
  4. Instead, You can send a message to yourself with Process.send_after

You should learn about processes, and You will understand their power.

If I mention those classes, it’s because they had great impact on my understanding.

Thanks for pointing out that oversight. OP has been corrected :slight_smile:

Thank you for sharing that :slight_smile:

Thanks for the resource, I really appreciate it :slight_smile:

A GenServer isn’t considered “started” until the init function returns - see GenServer.init/1 for more detail. Making main call itself means that init never returns.

1 Like