pubsubhub 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/pubsubhub.rb +124 -0
  3. metadata +102 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a3593b95bdec65c16c1ffb96905f6ca3031d4cf4
4
+ data.tar.gz: b5476d46c224486b036e4b89c7dd44077f34b4cc
5
+ SHA512:
6
+ metadata.gz: 8782b4ebddfd438745ab2dd5261b8365c4227fd9dad74ed7561dd8f1fc32ed1617a4fa79b1b59c6173e6ebcf3a61ed7f7d7d39f1d2c684bcd3c9279cdd819982
7
+ data.tar.gz: 2cb5b9378f5341349642bd338927d5bec8fc45043fe07833b4339044834b9c87a74e7cdfc46ae8e9ba5ea6a500bc08fc85bf68351b6750e60950edf0667c3d9a
data/lib/pubsubhub.rb ADDED
@@ -0,0 +1,124 @@
1
+ require 'forwardable'
2
+ require 'singleton'
3
+
4
+ # The `PubSubHub` provides a mechanism to subscribe to events and notify
5
+ # objects of events.
6
+ #
7
+ # To subscribe to an event, add a hash to
8
+ # {file:config/initializers/pub_sub_hub.rb}. The listener must implement
9
+ # `handle_#{event_name}`.
10
+ #
11
+ # # {file:config/initializers/pub_sub_hub.rb}
12
+ #
13
+ # PubSubHub.register(
14
+ # took_action: [
15
+ # { listener: Mailer, async: true },
16
+ # ],
17
+ # )
18
+ #
19
+ # To trigger an event, call `PubSubHub.trigger`. All the arguments are
20
+ # forwarded to the `listener`.
21
+ #
22
+ # class Action
23
+ # def take_action(person)
24
+ # # ...
25
+ # PubSubHub.trigger :took_action, self, person
26
+ # end
27
+ # end
28
+ #
29
+ # class Mailer
30
+ # def self.handle_took_action(action, person)
31
+ # # send `action.creator` an email
32
+ # end
33
+ # end
34
+ #
35
+ # By default, exceptions raised during event propagation are handled by printing
36
+ # them to standard error. You can set a custom handler by passing in a callable
37
+ # object to `PubSubHub.error_handler=`. We use this at Causes to integrate with
38
+ # our `Oops` plug-in, without creating a hard dependency on it:
39
+ #
40
+ # PubSubHub.error_handler = ->(exception) { Oops.log(exception) }
41
+ #
42
+ # Likewise, dispatch of `async: true` events is handled by a callable passed in
43
+ # to `PubSubHub.async_dispatcher=`. The default implementation just calls
44
+ # `Object#send` (ie. it is not actually asynchronous). At Causes, we've supplied
45
+ # a custom dispatcher that relies on the async_observer plug-in:
46
+ #
47
+ # PubSubHub.async_dispatcher = ->(listener, handler, args) do
48
+ # listener.async_send(handler, *args)
49
+ # end
50
+ #
51
+ class PubSubHub
52
+ include Singleton
53
+
54
+ VERSION = '0.0.1'
55
+
56
+ class << self
57
+ extend Forwardable
58
+
59
+ # Convenience methods:
60
+ def_delegators :instance,
61
+ :async_dispatcher,
62
+ :async_dispatcher=,
63
+ :error_handler,
64
+ :error_handler=,
65
+ :register,
66
+ :trigger
67
+ end
68
+
69
+ attr_accessor :async_dispatcher, :error_handler
70
+ attr_reader :registry
71
+
72
+ def initialize
73
+ @async_dispatcher = ->(listener, handler, args) do
74
+ listener.send(handler, *args)
75
+ end
76
+
77
+ @error_handler = ->(exception) { STDERR.puts exception }
78
+ end
79
+
80
+ def register(registry)
81
+ @registry = validate_registry!(registry)
82
+ end
83
+
84
+ # Notifies listeners of a event.
85
+ #
86
+ # Arguments are forwarded to the handlers. If the listener registered with
87
+ # `async: true`, `trigger` calls the handler using an asynchronous dispatcher.
88
+ #
89
+ # The default dispatcher just forwards the message directly. For an example of
90
+ # a dispatcher that is actually asynchronous, see
91
+ # {file:config/initializers/pub_sub_hub.rb}, which sets up:
92
+ #
93
+ # PubSubHub.async_dispatcher = ->(listener, handler, args) do
94
+ # listener.async_send(handler, *args)
95
+ # end
96
+ #
97
+ def trigger(event_name, *args)
98
+ @registry[event_name.to_sym].each do |registration|
99
+ begin
100
+ listener = registration[:listener]
101
+ async = registration[:async]
102
+ handler = :"handle_#{event_name}"
103
+
104
+ if async
105
+ @async_dispatcher.call(listener, handler, args)
106
+ else
107
+ listener.send(handler, *args)
108
+ end
109
+ rescue => e
110
+ @error_handler.call(e)
111
+ end
112
+ end
113
+ end
114
+
115
+ private
116
+
117
+ def validate_registry!(registry)
118
+ registry.each do |event_name, registrations|
119
+ registrations.any? do |registration|
120
+ raise ArgumentError unless registration[:listener]
121
+ end
122
+ end
123
+ end
124
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pubsubhub
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Causes Engineering
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-08-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mocha
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: PubSubHub allows you to loosen the coupling between components in a system
70
+ by providing a centralized registry of events and listeners that subscribe to them.
71
+ email:
72
+ - eng@causes.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - lib/pubsubhub.rb
78
+ homepage: https://github.com/causes/pubsubhub
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: 2.0.0
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.0.2
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Simple event-based publish-subscribe library
102
+ test_files: []