Event broker constraints document:
EventBroker.event
Caller’s constraints:
- I want to return immediately from calling this function.
- My responsibility for this event ends when I thus return.
- I want this event to be delivered expeditiously to any consumers who
may or may not be interested in it. - However, I have no synchronization requirements over such delivery.
- I also have no knowledge of what consumers may or may not exist.
Consumer’s constraints:
- I want to expeditiously receive any events which match subscriptions
I’ve made. - However, I have no synchronization requirements over such delivery.
- I want to receive each event I care about exactly once.
Broker’s constraints:
- I want to repeat any event I receive to all my subscribers.
- I know nothing about events.
Registry’s constraints:
none
Filter’s constraints:
- I want to repeat any event I receive which passes my filter function
to all my subscribers. - I know nothing about events besides whether or not they pass my
filter function.
Conclusions
event
should use asynchronous message sending, i.e. cast and info.- Each event should be completely handled within the callback receiving
it. - No synchronization is necessary during the process of handling an
event.
EventBroker.subscribe / EventBroker.unsubscribe
Caller’s constraints:
- I want to be (un)subscribed when I return from this call.
- I want to receive events matching the filter spec list I subscribed
to, if I subscribed. - I want to not receive events matching the filter spec list if I
unsubscribed (unless they match another subscription I also have).
Producer’s constraints:
- I know nothing about any consumers that may or may not exist or their
subscriptions.
Broker’s constraints:
- I know nothing about any subscribers except direct subscribers to me.
- I know nothing about whether any subscriber is a filter agent or a
final consumer. - I have no synchronization requirements; if a subscriber to me doesn’t
actually exist, I don’t care.
Registry’s constraints
- I want to maintain an accurate, up-to-date map of filter specs to
filter agents. - I have a synchronization requirement over this: if an agent in my map
does not exist, I may direct phantom subscriptions to a nonexistent
agent and falsely report success to the caller. - I have a synchronization requirement over this: if an agent that
exists is not in my map, I will fail to direct (un)subscriptions
correctly.
Filter’s constraints:
- I know nothing about any subscribers except direct subscribers to me.
- I know nothing about whether any subscriber is another filter agent
or a final consumer. - I know nothing about what I am subscribed to, whether it is another
filter agent or the broker. - I have no synchronization requirements; if a subscriber to me doesn’t
actually exist, I don’t care. - I want to reap myself if I have no remaining subscribers.
Conclusions
subscribe
andunsubscribe
are synchronous, and should be calls.- They should be calls on the Registry; only the caller and the Registry
have synchronization requirements. - The Registry should supervise or monitor all filters, and the Broker,
to maintain its map accurately.
Notes
- The reason we’re not just using the stock Registry module is because
we want flexible consumer-defined filters, and the stock Registry
module just works with term topics. However, it might be instructive
to look at how it handles registration just to see if any
synchronization gotchas are hidden therein. - The design does not deduplicate events, seemingly violating one of the
constraints! Rather, we rely on the ability of consumers to customize
their filter stack freely to write exactly the filter they want. The
ideal usage of this event broker is for each consumer to have exactly
one subscription to it. This should be emphasized in the
documentation. - Supervisors are meant to do exactly one thing: start and stop
children, using some strategy to deal with normal/abnormal stops. So
Registry won’t literally be a Supervisor, even if morally it
supervises.