cztop-reactor 0.1.0.pre20170316155217 → 0.1.0.pre20170323172345
Sign up to get free protection for your applications and to get access to all the features.
- 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
|