Are there use cases left where people still prefer to use GenEvent
over options like Registry
?
Yes? I’m a bit confused. They’re solving very different problems.
GenStage
is a closer replacement to GenEvent
than Registry
is.
I feel GenEvent
is often used to build a pub/sub system and I suspect it’s more common to default to Registry
for such uses now. I could totally be wrong.
Can you explain an example usage where GenEvent
is a great fit?
I feel bad that post is kind of heavy and that’s after I deleted a lot of stuff that really didn’t need to be explained anyway. But I’m going to try and summarize it into three needs first:
- If you need registry that monitors and deregisters dead tasks that also stores meta data and don’t mind the calling process dispatching messages to other processes,
Registry
is great. - If you need a different process that is dedicated to emitting events with backpressure,
GenStage
is great. - If you need an easy way to register an event handler that is managed by the process and can only be registered by name or with a particular resource once then
:gen_event
works for that quite well.
Well, Logger
uses :gen_event
for one good example. While GenEvent
isn’t quite the same as :gen_event
it’s pretty close.
Anyway, GenEvent
is a process that handles pretty much everything. Child processes are added through the GenEvent
process where callbacks are invoked, notified by the GenEvent
process, allows for backpressure in handling events, and doesn’t have to be started as a named process.
This is a great space for GenStage
to step in, since GenEvent
will be removed in Elixir 2.0.
But :gen_event
may still be used by Logger
and such, since a :gen_event
process registers handlers by initializing them from the gen_event
process.
Registry
is a process registry that allows for unique and duplicate sets. When a Registry
is started it always has a name. Unlike :gen_event
or GenStage
all dispatches are handled by the process calling Registry.dispatch/3
or Task
s spawned from the calling process. Basically everything that isn’t “unregistration” due to process exits is handled by the calling process.
Personally, even before Registry
was introduced, I used gproc
for pubsub. I can’t think of a case where I’d recommend GenEvent
.
Do we know this for sure? The current documentation does not mention deprecation.
It will be deprecated with 1.5. Also there’s this little comment.
So it seems like that is at least the plan.
Thanks for the info.
The only reason Logger uses :gen_event
is because it has to send large amounts of data. So a design such as the registry, which would require the same message to be copied to different handlers is less acceptable. That’s the only scenario where I would use :gen_event
.
Sometimes you can simply replace it by a supervisor too: http://blog.plataformatec.com.br/2016/11/replacing-genevent-by-a-supervisor-genserver/
I would consider a GenStage only if it suits GenStage, such as you are interacting with external systems and therefore you need/want back-pressure.