minhajuddin
Should we catch stray messages in a GenServer?
Catching stray messages which may fill up your message inbox is considered a good practice in erlang. Do we need to catch them even in a GenServer?
defmodule Ticker do
use GenServer
def handle_info(:tick, state) do
schedule_tick(state)# this makes sure that we catch up if a work is delayed
work(state)
{:noreply, state}
end
# to catch stray messages?
require Logger
def handle_info(oops, state) do
Logger.warn("UNEXPECTED_EVENT_IN_TICKER: #{inspect oops}")
{:noreply, state}
end
end
Marked As Solved
Qqwy
I made a PR and @josevalim was very quick to reply:
The GenServer always remove the message. If you don’t implement the callback, it means the GenServer will fail for unknown messages, which may actually be desired. So if you don’t want to define a catch-all clause, that’s ok.
So it seems that we arrived at an incorrect conclusion before.
Also Liked
sasajuric
Absolutely agree! I can’t recall a single time I didn’t write the catch-all handle_info. In contrast, I don’t think I ever wrote catch-all for handle_cast and handle_call.
hubertlepicki
Yes you should define it. And your hunch is good, for exactly the reason you mention.
Elixir’s intro docs on GenServer make it clear in this section:
fishcakez
I disagree with the consensus here. I don’t think there should be a catch all clause by default. I would like the handle_info/2 to crash in the default implementation just like handle_call/3 and handle_cast/2. Rather an explanation is required why you need the catch all - but if there is a catch all you must log. The reason we don’t crash by default in handle_info/2 is because we used to silently ignore it and didn’t log (there wasn’t a Logger).
Messages that come to handle_info/2 are likely from actions triggered by the process itself. For example monitor or port messages. In these situations you may want to disregard unhandled messages for old ports/monitors. However if the process is receiving monitor messages and the handle_info/2 clause catches all of :DOWN I would not write the clause because not expecting other messages. It would be overly defensive programming and there is a bug so want to crash.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









