async_emitter 1.0.0

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.
Files changed (3) hide show
  1. checksums.yaml +15 -0
  2. data/lib/async_emitter.rb +132 -0
  3. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OGI1OGE0ZDUzZTIwN2JiMmFmMWY5N2VhNDVlYWRjM2NjOTIwNGVjOQ==
5
+ data.tar.gz: !binary |-
6
+ NzFlMzk0NzAxNjJiZWQxNWI1ZDI3Y2MxNDRjMDQ1MDUzNDA4YzNjZQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZTRmNTJkOTBjMTRmYmJlYjIyZmRkM2Y4NzBmYjRiMmE0OWMwMmMzZWQ2NTRj
10
+ YjI0OGMwM2MyODgyOTA5NGIyNjU5Yjk5MTY3OTllNTJiZjI4NWVhZTA5NDlm
11
+ MmI2ZjMzMTY1MmVjNTRhYmU5NzJkMzlkMWNlOGU1NmQ1YzA1OGI=
12
+ data.tar.gz: !binary |-
13
+ OGVjMTJmYjc0MjYxZDdhMzMzYjU3NzkxMjU3OTQ2YmUyMTU2YjkyYmVmZTgw
14
+ MDcyMmNkZTUwNjdhNTIyMGM0ZmM1MDk3YzQ2ZmViMjQwYjAzOGNjMDU1MjY1
15
+ N2YwZjkxM2EzMzJkMWUwOWI4OTAwY2M5MzkxMjllYWU0Y2Q2YTc=
@@ -0,0 +1,132 @@
1
+ require 'thread'
2
+
3
+ class AsyncEmitter
4
+ =begin
5
+ The AsyncEmitter class provides a mechanism for asyncronous communication
6
+ in Ruby programs. Each instantiation provides notification of events
7
+ registered using any object that is valid as a Hash key. Multiple
8
+ events can be registered for each key and listeners can be registered
9
+ for one or many events. Listeners for a key event can be released.
10
+
11
+ example:
12
+ emitter = AsyncEmitter.new
13
+ emitter.on :error, lambda { |e| puts "Error: #{e}" }
14
+ emitter.on :data, lambda { |data| puts "Data: #{data}" }
15
+
16
+ begin
17
+ data = get_data_from_somewhere
18
+ emitter.emit :data, data
19
+ rescue Exception => e
20
+ emitter.emit :error, e
21
+ end
22
+
23
+ Where more then one listener is registered for an event they are
24
+ notified in the order they are recieved.
25
+ =end
26
+
27
+ def initialize
28
+ @emissions = {}
29
+ end
30
+
31
+
32
+ ########################################################################
33
+ # Register for notification
34
+ #
35
+ # token - any valid Hash key representing the event
36
+ # p - a procedure to be called on notification
37
+ # once_only - if true the notification is removed after being fired once
38
+ # ######################################################################
39
+ def on (token, p, once_only=false)
40
+ @emissions[token] ||= {}
41
+ @emissions[token][:p] ||= []
42
+ @emissions[token][:data] ||= []
43
+ @emissions[token][:semaphore] ||= Mutex.new
44
+ @emissions[token][:cv] ||= ConditionVariable.new
45
+
46
+ @emissions[token][:p].push Hash[:p => p, :o => once_only]
47
+
48
+ @emissions[token][:thread] ||= Thread.new do
49
+
50
+ @emissions[token][:active] = true
51
+
52
+ while @emissions[token][:active]
53
+ @emissions[token][:semaphore].synchronize do
54
+ self.post_data_for token
55
+ @emissions[token][:cv].wait @emissions[token][:semaphore]
56
+ if @emissions[token][:active]
57
+ self.post_data_for token
58
+ end
59
+ end
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ ########################################################################
67
+ # Register for single notification - convenience and self documenting
68
+ # method for: on token, proc, true
69
+ #
70
+ # token - any valid Hash key representing the event
71
+ # p - a procedure to be called on notification
72
+ # ######################################################################
73
+ def once (token, p)
74
+ self.on token, p, true
75
+ end
76
+
77
+ def emit (token, data)
78
+ @emissions[token][:semaphore] ||= Mutex.new
79
+ @emissions[token][:cv] ||= ConditionVariable.new
80
+ @emissions[token][:data] ||= []
81
+
82
+ @emissions[token][:semaphore].synchronize do
83
+ @emissions[token][:data].push data
84
+ @emissions[token][:cv].signal
85
+ end
86
+
87
+ end
88
+
89
+
90
+ ########################################################################
91
+ # Remove notification for an event
92
+ #
93
+ # token - Hash key representing the event
94
+ ########################################################################
95
+ def release (token)
96
+ @emissions[token][:active] = false
97
+ Thread.kill @emissions[token][:thread]
98
+ end
99
+
100
+ protected
101
+ def post_data_for (token)
102
+ @emissions[token][:p].each_index do |i|
103
+ o = @emissions[token][:p][i][:o]
104
+ p = @emissions[token][:p][i][:p]
105
+
106
+ if o
107
+ @emissions[token][:p].slice! i
108
+ end
109
+
110
+ if i >= @emissions[token][:p].length - 1
111
+ while @emissions[token][:data].length > 0 do
112
+ data = @emissions[token][:data].shift
113
+ p.call data
114
+ if o
115
+ @emissions[token][:data] = []
116
+ break
117
+ end
118
+ end
119
+ else
120
+ @emissions[token][:data].each do |data|
121
+ p.call data
122
+ if o
123
+ break
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+ end
130
+ end
131
+
132
+
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: async_emitter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Greg Martin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: An asyncronous emitter class for ruby
14
+ email: greg@softsprocket.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/async_emitter.rb
20
+ homepage: http://rubygems.org/gems/async_emitter.rb
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.4.6
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: AsyncEmitter
44
+ test_files: []