In this post, I make the case that gen_event’s default behaviour of executing installed event handlers one at a time is a good, flexible design. That doesn’t forgive gen_event’s other alleged faults, though.
Question: If gen_event ran handlers concurrently by default, how would you go about running handlers sequentially?
I don’t think it is a pretty common use case. However I very frequently need something like a gen_event that handles things concurrently and that doesn’t crash all the handlers if one handler crash. It is really easy to implement a sequential gen_event using a gen_server. Implementing each time something like José Valim wrote on his post is more difficult and error prone.
Unless a handler calls erlang:exit, it’s unlikely that the event manager will crash if a handler does. As I understand it, the default behavior is to remove (silently by default, or sending a message in the case of add_sup_handler) the failing handler and carry on.
That said, I think you have a point in that it’s reasonably simple to turn a gen_server into something almost identical to a gen_event, and avoid gen_event’s fiddly bits. My main point in the article is that I think that running handlers sequentially is a good default because of the affordances it offers developers.
I guess at this point I’m torn between whether or not it is better to have a design that is less broadly useful, but more flexible, versus one that is widely usable, but inflexible. Given this blog post, I’m currently leaning towards more flexible.
Question: If gen_event ran handlers concurrently by default, how would you go about running handlers sequentially?I don’t think it is a pretty common use case. However I very frequently need something like a gen_event that handles things concurrently and that doesn’t crash all the handlers if one handler crash. It is really easy to implement a sequential gen_event using a gen_server. Implementing each time something like José Valim wrote on his post is more difficult and error prone.
Unless a handler calls
erlang:exit, it’s unlikely that the event manager will crash if a handler does. As I understand it, the default behavior is to remove (silently by default, or sending a message in the case of add_sup_handler) the failing handler and carry on.That said, I think you have a point in that it’s reasonably simple to turn a gen_server into something almost identical to a gen_event, and avoid gen_event’s fiddly bits. My main point in the article is that I think that running handlers sequentially is a good default because of the affordances it offers developers.
I guess at this point I’m torn between whether or not it is better to have a design that is less broadly useful, but more flexible, versus one that is widely usable, but inflexible. Given this blog post, I’m currently leaning towards more flexible.
Thanks for reading!