Clearing out process mailbox - is using :c.flush() a good idea?

I’m working on a project that awaits an :ok signal while also trapping and awaiting any exits that happen midway. Looks something like this:

  Process.flag(:trap_exit, true)
  # Call a process that will send() back :ok after some time
  receive do
    :ok -> :nice
    {:EXIT, pid, reason} -> :bad
    {:EXIT, reason} -> :bad
  after
    10_000 ->
      :timeout
  end

The issue is that if there is an :EXIT that happened prior to running this function, it will instantly return :bad. So I was thinking about adding something like :c.flush() to clear out the mailbox before we start the receive, however I’m not really sure if this is really a good idea. Or perhaps I’m going down some dark path that I shouldn’t go into…

Would love to hear your opinion :skull:

Do you want to ignore the first exit signal if it comes before entering the receive block, or do you want to ensure that you don’t miss the ok that’s already in the mailbox but after the exit?

1 Like

I want to ignore whatever exit signals came in before the receive block, whatever exits happen whenever the receive block is running should prioritize exit. However I’m not sure if clearing our whole mailbox is a good thing

You can write a flush_exits like so:

defp flush_exits do
  receive do
    {:EXIT, _, _} -> flush_exits()
    {:EXIT, _} -> flush_exits()
  after
    0 -> :ok
  end
end

This will selectively remove exits from the mailbox, returning when there are none left. :slight_smile:

4 Likes

Oh right, this way just exits get cleared out, should be less destructive…

I guess that’s solved, thank you very much.

1 Like