Monitoring Processes (2/3)

Mar 24, 2024   Kero van Gelder
We will look at three approaches to work with a single crashing process, i.e. prevent it from taking down our entire Gleam program, namely:

Monitoring

We can setup monitors this way:
  let s: Selector(MainMsg) = process.new_selector()
  let assert Ok(a) = actor.start(Nil, loop)
  let assert Ok(pid) = actor.to_erlang_start_result(Ok(a))
  let monitor = process.monitor_process(pid)
  let s2 = process.selecting_process_down(s, monitor, ActorExited)
and -if you are lucky- you can experience that you do get a message, notifying you that your actor perished.

However, since the actor is linked, your main process will still crash.

Non-linked Processes

The obvious use-case for monitors, then, is for processes that are from Erlang dependencies.

Note that process.start() is passed a boolean to start the process linked or non-linked. A non-linked process does not crash the creating process, nor send exit messages. If you do not care whether a process lives or not, a non-linked process is all you need.

Monitoring a non-linked process

For completeness sake, let us start a process (not an actor) from Gleam, and monitor that. We take some code from our Gleam OTP post (ignore the subjects, we can crash without them) and combine it with the above and the post about trapping exits.
import gleam/erlang/process.{type ProcessDown, ProcessDown, type Selector, type Subject}

type MainMsg {
  ActorExited(ProcessDown)
}

pub fn main() {
  let pid =
    process.start(
      running: fn() {
        let assert True = False
      },
      linked: False,
    )

  let s: Selector(MainMsg) = process.new_selector()
  let monitor = process.monitor_process(pid)
  let s2 = process.selecting_process_down(s, monitor, ActorExited)

  case process.select_forever(s2) {
    ActorExited(ProcessDown(pid, reason)) -> Nil
  }
}
! There is a race condition here; but due to this (excerpt from Erlang docs)

"If Pid2 does not exist, the 'DOWN' message is sent immediately with Reason set to noproc."

you will receive a down message, regardless.