Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass the name of the event as a final argument #103

Closed
chrisnicola opened this issue Feb 26, 2015 · 7 comments
Closed

Pass the name of the event as a final argument #103

chrisnicola opened this issue Feb 26, 2015 · 7 comments

Comments

@chrisnicola
Copy link

It is possible to subscribe to all or multiple events with a single method using :with. It would make sense not to lose information on the subscriber side of the event name. This is useful in cross cutting subscribers like logging or analytics.

Currently I'm working around this with method_missing.

Would be happy to submit a PR if this is a sensible idea.

@krisleech
Copy link
Owner

I not sure I understand, can you give an example of what the API would look like please?

@chrisnicola
Copy link
Author

Something like this.

Wisper.subscribe(LoggerSubscriber.new, with: :log_event)

class LoggerSubscriber

  def log_event(*args, event_name)
    logger.info "#{event_name} occurred"
  end
end

@krisleech
Copy link
Owner

My gut feeling is the PR would add too much complexity in terms of code branching to be acceptable.

But there is a way. You could write a custom broadcaster which passes the event name in addition to the args.

Have a look here for more information. You could even release a gem :)

Let me know if you have any problems.

@chrisnicola
Copy link
Author

No problem. As I said I found a simple enough solution to the issue.

@krisleech
Copy link
Owner

I think one of your comments has gone missing :)

Feel free to update the Wiki if you think the solution would be helpful to others.

@nepalez
Copy link
Contributor

nepalez commented Feb 26, 2015

Except for method_missing there is one more way to solve the problem
of this type.

I define a listener as a decorator, providing necessary callbacks. In the
decorator I define two additional methods: #otherwise and #finalize.

The first one does some default actions, the second one calls #otherwise
when no expected notification has been received beforehand.

  class Listener < SimpleDelegator

    def on_success
      # ...do something
    end

    # ... other callbacks the listener looks for

    def otherwise
      # ...do something
    end

    def finalize
      otherwise unless @notified
    end

    # the publisher checks callback existense before calling it,
    # and @notified remembers the fact
    def respond_to?(*)
      super ? (@notified = true) : false
    end
  end

The bright side of this trick is I can separate callbacks the listener looks for
from any others (including the case the publisher dies silently and sends
nothing).

The dark side is I need to explicitly call #finalize after service call.

  publisher.subscribe listener
  publisher.call # does something and sends notifications
  listener.finalize

I don't think it is a universal solution, but in controllers or
when one publisher calls another and listens to its notification, it
works fine.

@chrisnicola
Copy link
Author

@krisleech I was referring to using method_missing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants