Closed lukeredpath closed 5 years ago
I don't have time to look at your proposal right now but to be honest it is unlikely that I would except such as feature as the complexity added to the codebase would likely outweigh the gains. But open to discussion.
It seems to be the same problem as handling different versions of an event. Say we have a version
attribute in the event payload and it is bumped as per semver when the payload changes.
It might look like:
class MyListener::V1
def on_event(event)
return unless event.fetch(:version) == 1
# ...
end
class MyListener::V2; end
Or have a single listener which delegates to a specialized handler:
class MyListener
def on_event(event)
case event.fetch(:version)
when "a"
V1.call(event)
when 2
V2.call(event)
else
raise
end
end
You could also replace the case
with eval
, const_get
, or constantize
(activesupport).
What level of complexity do you anticipate this feature would add? The implementation would seem fairly straightforward I think. I do intend to do a spike on it and see if this is true.
I will explore the idea of some kind of delegating proxy/decorator though.
What level of complexity do you anticipate this feature would add?
Any additional code has a cost which is why I'm pretty adverse to adding additional features to Wisper.
There are some features I regret adding (e.g. on, with, prefix options) which like this requirement can be handled easily by the listener.
I could see the earlier examples being gemified for easy application to any listener.
Do you have a particular objection to handling this in the listener?
This is something I might consider submitting a PR for in the future but I wanted to raise an issue for discussion first to see what people thought of the idea.
We have a scenario in an app I'm working on where a single model, which I'll call
Widget
, broadcasts events throughout it's lifecycle. We have a workflow associated with these events and we drive that workflow by having a dedicatedWorkflow
class that subscribes to events fromWidget
. So far, so simple.The issue arises where
Widget
can have a particulartype
attribute. The events broadcast are the same but how we handle those events changes depending on the type - the different types have different workflows.The way we model this is to have a
WidgetTypeAWorkflow
andWidgetTypeBWorkflow
listener. The issue is ensuring that each listener only receives events fromWidget
if it has the corresponding type. We don't want to have a guard clause in each of our event listener methods. In an ideal world, I'd like to be able to filter out events fromWidget
based on the type at subscription time.Wisper only provides us with limited options for filtering out events - it does allow us to scope subscribers to particular broadcasters. Therefore, out current solution is to have two internal classes to
Widget
-TypeABroadcaster
andTypeBBroadcaster
and do a little bit of Ruby magic so what whenever we broadcast an event insideWidget
, it delegates broadcasting to a concrete broadcaster object of one of these types. This allows us to scope the two workflow classes to the specific broadcaster using the existingsource:
option.However, it feels like it would be nicer if we could just broadcast events without any of the above complexity and simply have our listeners specify how events should be filtered when they subscribe. It might look something like this:
You could have a built-in block based filter type that is initialised internally if the user passes a proc to the
filter:
option for convenince:You could also refactor internally and make the existing
source:
option work as a filter:Any thoughts on this?