cztop-reactor 0.1.0.pre20170316155217 → 0.1.0.pre20170323172345
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 +4 -4
- data/ChangeLog +19 -2
- data/lib/cztop/reactor.rb +46 -24
- data/spec/cztop/reactor_spec.rb +134 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 693a140ab57c4d6cd02f56f750474f7b8d2b1da1
|
4
|
+
data.tar.gz: c56488274eece275fab5ec9d5383d3956f6faf4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b1fce6cca68d902057ffd8efd008e14da2cb5ed14adf121f8af406c8f4fb1c9429598085dfb379f2ce357ec0ea51524753576e79ac0fe0aabdf0af92e56d10f
|
7
|
+
data.tar.gz: 26f53aa35c4762e46fc42add8cbe732a6b66c24896df5ddb35d997883a12dc3fcc4521a9b82f623c612fc41039c7b343af6ef7fb46724b800c6cbe0c3be60848
|
data/ChangeLog
CHANGED
@@ -1,12 +1,29 @@
|
|
1
|
+
2017-03-27 Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
* .gems:
|
4
|
+
Fix fivefish gem name in gemset
|
5
|
+
[27fcb613383f] [tip]
|
6
|
+
|
7
|
+
2017-03-22 Michael Granger <ged@FaerieMUD.org>
|
8
|
+
|
9
|
+
* .hoerc, cztop-reactor.gemspec, lib/cztop/reactor.rb,
|
10
|
+
spec/cztop/reactor_spec.rb:
|
11
|
+
Allow a handler object instead of a block.
|
12
|
+
[10904c471caa] [github/master]
|
13
|
+
|
1
14
|
2017-03-16 Michael Granger <ged@FaerieMUD.org>
|
2
15
|
|
16
|
+
* Rakefile, cztop-reactor.gemspec:
|
17
|
+
Add missing dependency on timers.
|
18
|
+
[962f88d917bf]
|
19
|
+
|
3
20
|
* .hgignore:
|
4
21
|
Ignore built gems
|
5
|
-
[594168b03b71]
|
22
|
+
[594168b03b71]
|
6
23
|
|
7
24
|
* README.md:
|
8
25
|
Fix link in the README
|
9
|
-
[0391133d132d]
|
26
|
+
[0391133d132d]
|
10
27
|
|
11
28
|
* .hgignore:
|
12
29
|
Ignore generated docs directory
|
data/lib/cztop/reactor.rb
CHANGED
@@ -100,7 +100,12 @@ class CZTop::Reactor
|
|
100
100
|
### event/handler+arguments pairs associated with the handle.
|
101
101
|
###
|
102
102
|
def register( socket, *events, &handler )
|
103
|
-
|
103
|
+
if !events.empty? && !events.last.is_a?( Symbol )
|
104
|
+
handler_obj = events.pop
|
105
|
+
handler = handler_obj.method( :handle_io_event )
|
106
|
+
end
|
107
|
+
|
108
|
+
raise LocalJumpError, "no block or handler given" unless handler
|
104
109
|
|
105
110
|
self.unregister( socket )
|
106
111
|
|
@@ -235,6 +240,11 @@ class CZTop::Reactor
|
|
235
240
|
### registered with the reactor for the `:read` event with the specified +callback+,
|
236
241
|
### then returned.
|
237
242
|
def register_monitor( socket, *events, &callback )
|
243
|
+
if !events.empty? && !events.last.is_a?( String )
|
244
|
+
handler = events.pop
|
245
|
+
callback = handler.method( :handle_monitor_event )
|
246
|
+
end
|
247
|
+
|
238
248
|
events.push( 'ALL' ) if events.empty?
|
239
249
|
|
240
250
|
monitor = CZTop::Monitor.new( socket )
|
@@ -253,33 +263,45 @@ class CZTop::Reactor
|
|
253
263
|
# Polling
|
254
264
|
#
|
255
265
|
|
256
|
-
### Poll
|
257
|
-
def start_polling
|
258
|
-
until self.empty?
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
if event
|
273
|
-
# self.log.debug "Got event: %p" % [ event ]
|
274
|
-
handler = self.sockets[ event.socket ][ :handler ]
|
275
|
-
handler.call( event ) if handler
|
266
|
+
### Poll registered sockets and fire timers until they're all unregistered.
|
267
|
+
def start_polling( **opts )
|
268
|
+
self.poll_once( **opts ) until self.empty?
|
269
|
+
end
|
270
|
+
|
271
|
+
|
272
|
+
### Poll registered sockets or fire timers and return.
|
273
|
+
def poll_once( ignore_interrupts: false, ignore_eagain: true )
|
274
|
+
self.log.debug "Polling %d sockets" % [ self.sockets.length ]
|
275
|
+
|
276
|
+
wait_interval = self.timers.wait_interval || DEFAULT_POLL_INTERVAL
|
277
|
+
|
278
|
+
# If there's a timer already due to fire, don't wait at all
|
279
|
+
event = if wait_interval > 0
|
280
|
+
self.log.debug "Waiting for IO for %fms" % [ wait_interval * 1000 ]
|
281
|
+
self.wait( wait_interval * 1000 )
|
276
282
|
else
|
277
|
-
|
278
|
-
self.timers.fire
|
283
|
+
nil
|
279
284
|
end
|
280
285
|
|
281
|
-
|
286
|
+
self.log.debug "Got event %p" % [ event ]
|
287
|
+
if event
|
288
|
+
# self.log.debug "Got event: %p" % [ event ]
|
289
|
+
handler = self.sockets[ event.socket ][ :handler ]
|
290
|
+
handler.call( event )
|
291
|
+
else
|
292
|
+
self.log.debug "Expired: firing timers."
|
293
|
+
self.timers.fire
|
282
294
|
end
|
295
|
+
|
296
|
+
self.log.debug "%d sockets after polling: %p" % [ self.sockets.length, self.sockets ]
|
297
|
+
rescue Interrupt
|
298
|
+
raise unless ignore_interrupts
|
299
|
+
self.log.debug "Interrupted."
|
300
|
+
return nil
|
301
|
+
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
302
|
+
raise unless ignore_eagain
|
303
|
+
self.log.debug "EAGAIN"
|
304
|
+
return nil
|
283
305
|
end
|
284
306
|
|
285
307
|
|
data/spec/cztop/reactor_spec.rb
CHANGED
@@ -9,6 +9,13 @@ require 'cztop/reactor'
|
|
9
9
|
describe CZTop::Reactor do
|
10
10
|
|
11
11
|
let( :reactor ) { described_class.new }
|
12
|
+
let( :handler_class ) do
|
13
|
+
Class.new do
|
14
|
+
def handle_io_event(ev); end
|
15
|
+
def handle_monitor_event(ev); end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
let( :handler_object ) { handler_class.new }
|
12
19
|
|
13
20
|
|
14
21
|
describe "socket registration" do
|
@@ -42,10 +49,22 @@ describe CZTop::Reactor do
|
|
42
49
|
end
|
43
50
|
|
44
51
|
|
45
|
-
it "
|
52
|
+
it "allows a socket to be registered with a handler object instead of a block" do
|
53
|
+
expect( reactor ).to_not be_registered( socket )
|
54
|
+
expect( reactor ).to_not have_event_enabled( socket, :read )
|
55
|
+
expect( reactor ).to_not have_event_enabled( socket, :write )
|
56
|
+
|
57
|
+
reactor.register( socket, :read, :write, handler_object )
|
58
|
+
|
59
|
+
expect( reactor ).to be_registered( socket )
|
60
|
+
expect( reactor ).to have_event_enabled( socket, :read )
|
61
|
+
expect( reactor ).to have_event_enabled( socket, :write )
|
62
|
+
end
|
63
|
+
|
64
|
+
it "errors if no block or handler object is given when registering a socket" do
|
46
65
|
expect {
|
47
66
|
reactor.register( socket, :read )
|
48
|
-
}.to raise_error( LocalJumpError, /no handler/i )
|
67
|
+
}.to raise_error( LocalJumpError, /no block or handler/i )
|
49
68
|
end
|
50
69
|
|
51
70
|
|
@@ -107,6 +126,64 @@ describe CZTop::Reactor do
|
|
107
126
|
end
|
108
127
|
|
109
128
|
|
129
|
+
describe "handler registration" do
|
130
|
+
|
131
|
+
let( :reader ) do
|
132
|
+
sock = CZTop::Socket::PAIR.new( '@inproc://callback-test' )
|
133
|
+
sock.options.linger = 0
|
134
|
+
sock
|
135
|
+
end
|
136
|
+
let( :writer ) do
|
137
|
+
sock = CZTop::Socket::PAIR.new( '>inproc://callback-test' )
|
138
|
+
sock.options.linger = 0
|
139
|
+
sock
|
140
|
+
end
|
141
|
+
|
142
|
+
after( :each ) do
|
143
|
+
reader.close
|
144
|
+
writer.close
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
it "calls a callback when a registered socket becomes readable" do
|
149
|
+
callback_called = false
|
150
|
+
data = nil
|
151
|
+
|
152
|
+
reactor.register( reader, :read ) do |event|
|
153
|
+
expect( event ).to be_a( CZTop::Reactor::Event )
|
154
|
+
expect( event ).to be_readable
|
155
|
+
expect( event ).to_not be_writable
|
156
|
+
expect( event.socket ).to equal( reader )
|
157
|
+
|
158
|
+
event.socket.receive
|
159
|
+
callback_called = true
|
160
|
+
end
|
161
|
+
|
162
|
+
writer << "stuff"
|
163
|
+
|
164
|
+
reactor.poll_once
|
165
|
+
|
166
|
+
expect( callback_called ).to be_truthy
|
167
|
+
end
|
168
|
+
|
169
|
+
|
170
|
+
it "calls #handle_io_event on a handler object when a socket becomes readable" do
|
171
|
+
handler_object = Object.new
|
172
|
+
expect( handler_object ).to receive( :handle_io_event ) do |event|
|
173
|
+
expect( event ).to be_a( CZTop::Reactor::Event )
|
174
|
+
expect( event ).to be_readable
|
175
|
+
expect( event ).to_not be_writable
|
176
|
+
expect( event.socket ).to equal( reader )
|
177
|
+
end
|
178
|
+
|
179
|
+
reactor.register( reader, :read, handler_object )
|
180
|
+
writer << "stuff"
|
181
|
+
reactor.poll_once
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
|
110
187
|
describe "timer registration" do
|
111
188
|
|
112
189
|
it "allows a callback to be called after a certain amount of time" do
|
@@ -143,6 +220,26 @@ describe CZTop::Reactor do
|
|
143
220
|
end
|
144
221
|
end
|
145
222
|
|
223
|
+
|
224
|
+
it "can create and register a monitor with a handler object instead of a block" do
|
225
|
+
socket = CZTop::Socket::REP.new
|
226
|
+
begin
|
227
|
+
monitor = reactor.register_monitor( socket, handler_object ) {}
|
228
|
+
expect( monitor ).to be_a( CZTop::Monitor )
|
229
|
+
expect( reactor ).to be_registered( monitor.actor )
|
230
|
+
ensure
|
231
|
+
monitor.terminate if monitor
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
|
236
|
+
it "raises an error when registering a monitor with no callback or handler object" do
|
237
|
+
socket = CZTop::Socket::REP.new
|
238
|
+
expect {
|
239
|
+
reactor.register_monitor( socket )
|
240
|
+
}.to raise_error( LocalJumpError, /no block or handler/i )
|
241
|
+
end
|
242
|
+
|
146
243
|
end
|
147
244
|
|
148
245
|
|
@@ -176,6 +273,41 @@ describe CZTop::Reactor do
|
|
176
273
|
end
|
177
274
|
|
178
275
|
|
276
|
+
it "doesn't trap interrupts by default" do
|
277
|
+
expect( CZTop::Poller::ZMQ ).to receive( :poller_wait ).
|
278
|
+
and_raise( Interrupt.new )
|
279
|
+
|
280
|
+
expect {
|
281
|
+
reactor.poll_once
|
282
|
+
}.to raise_error( Interrupt )
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
it "has an option to ignore interrupts if you're doing your own signal-handling'" do
|
287
|
+
expect( CZTop::Poller::ZMQ ).to receive( :poller_wait ).
|
288
|
+
and_raise( Interrupt.new )
|
289
|
+
|
290
|
+
expect( reactor.poll_once(ignore_interrupts: true) ).to be_nil
|
291
|
+
end
|
292
|
+
|
293
|
+
|
294
|
+
it "ignores EAGAIN/EWOULDBLOCK by default" do
|
295
|
+
expect( CZTop::Poller::ZMQ ).to receive( :poller_wait ).
|
296
|
+
and_raise( Errno::EWOULDBLOCK.new )
|
297
|
+
|
298
|
+
expect( reactor.poll_once ).to be_nil
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
it "has an option to propagate EGAIN/EWOULDBLOCK" do
|
303
|
+
expect( CZTop::Poller::ZMQ ).to receive( :poller_wait ).
|
304
|
+
and_raise( Errno::EAGAIN.new )
|
305
|
+
|
306
|
+
expect {
|
307
|
+
reactor.poll_once( ignore_eagain: false )
|
308
|
+
}.to raise_error( Errno::EAGAIN )
|
309
|
+
end
|
310
|
+
|
179
311
|
end
|
180
312
|
|
181
313
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cztop-reactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.pre20170323172345
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
w8aNA5re5+Rt/Vvjxj5AcEnZnZiz5x959NaddQocX32Z1unHw44pzRNUur1GInfW
|
36
36
|
p4vpx2kUSFSAGjtCbDGTNV2AH8w9OU4xEmNz8c5lyoA=
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2017-03-
|
38
|
+
date: 2017-03-24 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: loggability
|