shouter 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 862686691e817c5a4673b19b99d32c67972dc50b
4
- data.tar.gz: ca15331f3a161e1fa990405430bcf9cbbac97a1e
3
+ metadata.gz: fca38a3d0a7a4056957ca27de249842abb520d76
4
+ data.tar.gz: 88aa5fc1c271e34e4882c5f38792a6c18fcbf6b7
5
5
  SHA512:
6
- metadata.gz: 72ad83a1d5cb0b462281464213c0e58651b315cc582c21b022e1feb1c2e1084a9254f7d393bb04c504be182c43605ddd1f6d63f4342cc0e89fd996dd6336e6f1
7
- data.tar.gz: 0506b4d5a87e8ae891de958e3d7ebadd8423e6e2461a41b31a49bafa3c09138b1b534b43d949d4a2a650893e22348532471f9a6d6f63890229518bbd9945a848
6
+ metadata.gz: 84b86db63d5054ac46eff0b5a8100a8ede7e0460b0521aa1131e8608c2f9121c9d7b20b0b77e94987947963ca5d30ddac393cc62e7ef1676119b85b1faca072c
7
+ data.tar.gz: e915ec735684d0956991631029d102ec55600ec06ae8e21633cd7ded6728859026f6ff5244369d66a2b6ce96c888ff22a20997303328cc7fc2b7f02b474a8d1e
data/README.md CHANGED
@@ -37,6 +37,18 @@ end
37
37
  A.publish(:my_scope, :on_change)
38
38
  => "I`m changed"
39
39
  ```
40
+ Since version `0.1.3` if you want asyncronous execution, using separate threads you can supply
41
+ the `async` option. By default it is set to `false`
42
+ ```ruby
43
+ class A
44
+ extend Shouter
45
+ subscribe(Listener.new, for: :my_async_scope, async: true)
46
+ end
47
+ ```
48
+ Now whenever you `publish` and event it will be run in a separate
49
+ thread. If a thread for the execution is already present another one
50
+ will not be created. If you have supplied a callback option it will be
51
+ executed in the thread of execution of the listener.
40
52
 
41
53
  You can subscribe multiple objects:
42
54
  ```ruby
@@ -59,7 +71,6 @@ A.publish(:my_scope, :on_change)
59
71
 
60
72
  A.publish(:my_scope, :on_change)
61
73
  => nil
62
-
63
74
  ```
64
75
  All the arguments are passed to the method as well:
65
76
  ```ruby
@@ -1,10 +1,20 @@
1
1
  require 'shouter/version'
2
2
  require 'shouter/hook'
3
3
  require 'shouter/guard'
4
- require 'shouter/listener'
4
+ require 'shouter/mixin'
5
+ require 'shouter/listeners/async'
6
+ require 'shouter/listeners/sync'
5
7
  require 'shouter/store'
8
+ require 'shouter/builder'
6
9
 
7
10
  module Shouter
11
+
12
+ class ScopeMissingError < StandardError
13
+ def initialize
14
+ 'You must supply a scope for running the events'
15
+ end
16
+ end
17
+
8
18
  def subscribe(*objects, **options)
9
19
  Shouter::Store.register(objects, options)
10
20
  end
@@ -0,0 +1,14 @@
1
+ module Shouter
2
+ class Builder
3
+ class << self
4
+ def register(object, options)
5
+ if options[:async]
6
+ _klass = Shouter::Listeners::Async
7
+ else
8
+ _klass = Shouter::Listeners::Sync
9
+ end
10
+ _klass.new(object, options)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,34 @@
1
+ module Shouter
2
+ module Listeners
3
+ class Async
4
+
5
+ include Shouter::Mixin
6
+
7
+ attr_reader :thread_exists
8
+
9
+ def notify!(scope, event, args, &block)
10
+ return unless notify?(scope, event)
11
+ return if thread_exists?
12
+
13
+ create_thread
14
+ Thread.new do
15
+ object.public_send(event, *args)
16
+ fire_hook!(options[:callback] || block)
17
+ end
18
+ unregister(object)
19
+ end
20
+
21
+ private
22
+
23
+ # If a thread is already spawned for this listener
24
+ # do not create another one
25
+ def thread_exists?
26
+ thread_exists
27
+ end
28
+
29
+ def create_thread
30
+ @thread_exists = true
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ module Shouter
2
+ module Listeners
3
+ class Sync
4
+
5
+ include Shouter::Mixin
6
+
7
+ def notify!(scope, event, args, &block)
8
+ return unless notify?(scope, event)
9
+
10
+ object.public_send(event, *args)
11
+ fire_hook!(options[:callback] || block)
12
+
13
+ unregister(object)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ module Shouter
2
+ module Mixin
3
+
4
+ def self.included(base)
5
+ base.include InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+
10
+ attr_reader :object, :options, :scope
11
+
12
+ def initialize(object, options)
13
+ raise Shouter::ScopeMissingError unless options[:scope]
14
+
15
+ @object = object
16
+ @options = options
17
+ @scope = options[:scope]
18
+ end
19
+
20
+ private
21
+
22
+ def notify?(scope, event)
23
+ return false unless notification_allowed?(event, scope)
24
+ return false unless fire_guard!
25
+ true
26
+ end
27
+
28
+ def unregister(object)
29
+ Store.unregister(object) if single?
30
+ end
31
+
32
+ def notification_allowed?(event, desired_scope)
33
+ object.respond_to?(event) && scope == desired_scope
34
+ end
35
+
36
+ def fire_hook!(callback)
37
+ Shouter::Hook.(callback)
38
+ end
39
+
40
+ def fire_guard!
41
+ Shouter::Guard.(options[:guard])
42
+ end
43
+
44
+ def single?
45
+ options[:single] == true
46
+ end
47
+ end
48
+ end
49
+ end
@@ -20,7 +20,9 @@ module Shouter
20
20
  mutex.synchronize do
21
21
  objects.each do |object|
22
22
  subscribed_objects = @@listeners.map(&:object)
23
- @@listeners << Shouter::Listener.new(object, options) unless subscribed_objects.include?(object)
23
+ # Got through a builder class based on whether it is a sync or async listener
24
+ # Should Return Shouter::Listener
25
+ @@listeners << Shouter::Builder.register(object, options) unless subscribed_objects.include?(object)
24
26
  end
25
27
  end
26
28
  end
@@ -40,7 +42,7 @@ module Shouter
40
42
  def notify(scope, event, args, &block)
41
43
  return if listeners.empty?
42
44
 
43
- listeners.each { |listener| listener.notify(scope, event, args, &block) }
45
+ listeners.each { |listener| listener.notify!(scope, event, args, &block) }
44
46
  end
45
47
 
46
48
  def listeners
@@ -1,3 +1,3 @@
1
1
  module Shouter
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shouter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Slaveykov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-19 00:00:00.000000000 Z
11
+ date: 2017-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -70,11 +70,12 @@ files:
70
70
  - bin/console
71
71
  - bin/setup
72
72
  - lib/shouter.rb
73
+ - lib/shouter/builder.rb
73
74
  - lib/shouter/guard.rb
74
75
  - lib/shouter/hook.rb
75
- - lib/shouter/listener.rb
76
- - lib/shouter/registry/async.rb
77
- - lib/shouter/registry/sync.rb
76
+ - lib/shouter/listeners/async.rb
77
+ - lib/shouter/listeners/sync.rb
78
+ - lib/shouter/mixin.rb
78
79
  - lib/shouter/store.rb
79
80
  - lib/shouter/version.rb
80
81
  - shouter.gemspec
@@ -1,57 +0,0 @@
1
- module Shouter
2
-
3
- class ScopeMissingError < StandardError
4
- def initialize
5
- 'You must supply a scope for running the events'
6
- end
7
- end
8
-
9
- class Listener
10
- attr_reader :object, :options, :scope
11
-
12
- def initialize(object, options)
13
- raise Shouter::ScopeMissingError unless options[:scope]
14
-
15
- @object = object
16
- @options = options
17
- @scope = options[:scope]
18
- end
19
-
20
- def notify(scope, event, args, &block)
21
- return unless notification_allowed?(event, scope)
22
-
23
- if fire_guard!
24
- object.public_send(event, *args)
25
- fire_hook!(callback || block)
26
-
27
- Store.unregister(object) if single?
28
- end
29
- end
30
-
31
- private
32
-
33
- def notification_allowed?(event, desired_scope)
34
- object.respond_to?(event) && scope == desired_scope
35
- end
36
-
37
- def fire_hook!(callback)
38
- Shouter::Hook.(callback)
39
- end
40
-
41
- def fire_guard!
42
- Shouter::Guard.(guard)
43
- end
44
-
45
- def callback
46
- options[:callback]
47
- end
48
-
49
- def single?
50
- options[:single] == true
51
- end
52
-
53
- def guard
54
- options[:guard]
55
- end
56
- end
57
- end
File without changes
File without changes