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.
- checksums.yaml +15 -0
- data/lib/async_emitter.rb +132 -0
- 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: []
|