shouter 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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