Yes, let's please add logging to handle_info throughout Elixir (including GenStage). :)
*José Valim* www.plataformatec.com.br Skype: jv.ptec Founder and Director of R&D On Thu, Sep 29, 2016 at 1:42 AM, James Fish <[email protected]> wrote: > Going from silently ignoring to crashing might be too much of a step. It > would certainly be possible for there to be unhandled messages people don't > know about. Should we log for at least the next release cycle? > > On 24 September 2016 at 18:24, James Fish <[email protected]> wrote: > >> When I saw this thread I thought we should be logging in the default >> `handle_info/2` implementation, regardless of the changes proposed here, >> because we are silently ignoring an unhandled message. This could certainly >> hide bugs as described by Alexei, we got this one wrong and need to change >> the default behaviour. However if we are logging `handle_info/2` should we >> avoid crashing and do similarly for `handle_call/3` and `handle_cast/2`? >> >> For `handle_call/3`, if we log and reply then the caller may handle the >> error and if we log and noreply then the caller blocks for the timeout, >> which could be infinity. Therefore even though we are logging a message it >> requires handling by a human. A well designed supervision tree (and a >> poorly designed one can too) will limit the fault to the minimal error >> kernel and recover to a (hopefully) good state as soon as possible after a >> crash. In many cases the error will happen either nearly all the time and >> be caught early in the development cycle or will happen very rarely and can >> be fixed when priorities allow. This could be somewhere from immediately to >> never such is the beauty of OTP's "let it crash" philosophy. >> >> With this in mind it makes sense to crash on unexpected calls/casts/other >> messages so that we can use the supervision tree to recover the system to a >> good state. These can occur for three reasons: >> >> 1) The message is intended for the GenServer but the server is in a bad >> state >> 2) The message is intended for the GenServer but the sender is in a bad >> state >> 2) The message is not intended for the GenServer and the sender is in a >> bad state >> >> We can not recover from a bad state to a good state by logging alone. >> >> Currently `handle_call/3` and `handle_cast/2` have different behaviour to >> `handle_info/2` because calls and cast should only be triggered by function >> calls to the callback module from client processes. This means an unhandled >> call or cast is definitely bad state somewhere. Whereas `handle_info/2` is >> more likely to be a result of a function call made by the GenServer. Common >> examples would starting async tasks, monitors, links, ports and sockets. In >> many situations some messages can be safely ignored, such as for async >> tasks where the :DOWN can be ignored after receiving the result message. >> Therefore it is a common pattern to have a catch all clause as the last >> function clause for `handle_info/2` but not `handle_call/3` and >> `handle_cast/2`. >> >> When struggling with these problems I often look at the OTP source to see >> how it is handled there. The supervisor is the corner stone of OTP and it >> logs unexpected messages: https://github.com/erlang/otp/ >> blob/41d1444bb13317f78fdf600a7102ff9f7cb12d13/lib/stdlib/ >> src/supervisor.erl#L630. However a supervisor can run user code, in the >> `init/1` or `start` function. Both of these can be called and have >> exceptions caught and the supervisor will continue to run. These cause >> unhandled messages, one example would be catching a `GenServer.call/3` >> timeout, which can lead to an unexpected response message arriving later. >> This type of handling is not normal though. >> >> If `handle_info/2` is not implemented then miscellaneous messages are not >> expected and perhaps should crash in the default implementation. Clearly >> something has gone wrong and there is a bug. When there is a bug the >> default behaviour in OTP is to crash and allow the supervision tree to do >> its work. Once the bug is understood then explicit handling is added, such >> as logging the unhandled message. I think we should crash in default >> implementation `handle_info/2` as with `handle_call/3` and `handle_cast/2`. >> >> On 23 September 2016 at 21:38, José Valim <[email protected]. >> br> wrote: >> >>> 2. The default implementation of handle_info/1 will exit on any >>>> incoming message, in the same way handle_cast/2 and handle_call/3 already >>>> do. >>>> >>> >>> I believe this is not a good default because your processes may receive >>> regular messages from other processes and you don't want to crash because >>> of them. This is much more unlikely to happen with cast and call though, so >>> we can afford to raise in cast and calls. >>> >>> I am wondering if the best way to solve this problem would be to have a >>> @before_compile callback that checks if you defined any of the callbacks >>> with a different arity while, at the same time, did not define one with the >>> proper arity. >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "elixir-lang-core" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to [email protected]. >>> To view this discussion on the web visit https://groups.google.com/d/ms >>> gid/elixir-lang-core/CAGnRm4JqC6rzBUYJHd9ij%3DQRH9-mPNDG1qGk >>> 1hTMZ6r331iZKA%40mail.gmail.com >>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JqC6rzBUYJHd9ij%3DQRH9-mPNDG1qGk1hTMZ6r331iZKA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit https://groups.google.com/d/ > msgid/elixir-lang-core/CA%2BibZ98WrNhF0Xo_mbVn- > ST2b9ysqryOCPoLWNf-jM7baisH2g%40mail.gmail.com > <https://groups.google.com/d/msgid/elixir-lang-core/CA%2BibZ98WrNhF0Xo_mbVn-ST2b9ysqryOCPoLWNf-jM7baisH2g%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Kj2j7q9CFjdZ_E0q8cWPxN5i4xu3NSBa%3DYgwUZRWoX7w%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
