Recommended API for subscription

Im triing to design API for library that will allow to subscribe for some events (more like state updates so first massage will by current state and other partial updates of it, but I’m trying to keep it simple so it can be one kind of event) and I’m struggling since there are more options:

  • streams
  • behaviour (what if client want to start subscription dynamicali?)
  • send message to pid (like HTTPoison async request handling, but absence of type check in this case make me uncomfortable, also is starting process out of supervision tree and link it to current process)
  • create subscribe function that accepts module and function as arguments and call them on every event (allow library to have own supervision tree and use response from function to control subscription, but again, absence of typecheck)

What would you recommend and why?

Maybe the Registry would be what you are looking for?

1 Like

Can you elaborate a little more? How would subscribe function look like? Only think that came into mi mind is httpoison solution, so sending pid to subscribe function,

thank you for your response :slight_smile:

:wave:

https://hexdocs.pm/elixir/master/Registry.html#module-using-as-a-pubsub

The process would subscribe to a relevant topic like "#{your_lib_name}:#{some_event}" and your library would publish to it once the event happens.

To keep things configurable to the end user, you might want to allow for callbacks (with your own using the registry being the default) passed in.

Like

YourApp.start_link(on_event: fn event -> Registry.dispatch(...) end) # so that the user can pick how they receive the messages from your app themselves
1 Like

Nice idea to make it configurable, I did not consider to pass callback on gen_server start, I will experiment a little bit with it. I read about and dispatch, but in mi case is not exactly pubsub since I need to do some extra work on every subscription start like push all the state data. I probably was not exactly clear, I would like to cover these cases:

  • push some standard events on every subscribe
  • prevent overflow in case someone call subscribe function on gen_server init (for instance I experiment with version subscribe(topic, callback) but when gen_server crashed and get restarted, old subscription stayed alive and new was created)
  • don’t force people to use single process to work with events (for instance if someone want to use poolboy and call transaction on every event), but this seems more like utopia
  • enforce typesafety as much as possible
  • allow for dynamic subscribe and unsubscribe during runtime

I think first case is eliminating registry and also registry is how I would like to dispatch events, I think it is kind of best practice to not show to client application what I use for dispatching events, so I can change it in the future (for instance phoenix pubsub),

Now I’m using solution where I have subscribe(topic, module, function, arguments) and I have own dynamic supervisor with register where key in register is all the arguments from subscribe, so if someone calls twice subscribe with same arguments, it will not start new subscription, but restart old one (so receiving module/function gets all the starting events again)

To be honest, that I can restart subscription on calling subscribe again I just realized during writing answer and that is basicaly solving mi problem, thank you :slight_smile: