arachni-reactor 0.1.0.beta3 → 0.1.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5989fe0374a4304051e3721c67783a8b879ff637
4
- data.tar.gz: fff4c26e3ee024205bf7946dbe5b28bb341fd8b2
3
+ metadata.gz: 07cb101ec43a769f658e301e43ba0ff218d5c4a3
4
+ data.tar.gz: 45a67ca1fef76ca161b5a3f216e260bd8c7c1494
5
5
  SHA512:
6
- metadata.gz: 22c792fe5cf32aa57e084cda14df281f9eb2faa059f79f97c71c008ec4c08f6070eb4332e6fdd33861f1e1a488cac66235edc4d573392d558d7deec0ac675702
7
- data.tar.gz: ce944f7922fa5d6034a79c37e3d85cadca8dde0f6595760727049bea3a624ea305ed1fa1a790cc729c8168c9486599bfd0bc358ad68f3248a425285376d05449
6
+ metadata.gz: c50a6d170e2e1ec78b6e5fb7b1216273aee8ee33df92e2d70c7ec8bfcf2ac9635cc9b8a45b8b2423494c4935450a23ab20f7b9b5b7ae298424dcc763217d4284
7
+ data.tar.gz: 6beda8054a8dd07ba2b20eba5213e473c95954fb9b3d37aae9b63f955c3938bfbd06cad11bf704086e34ffa71ecaa16ceda8369db6c6e478ba62906635ff0019
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # ChangeLog
2
2
 
3
+ ## Version 0.1.0.beta4
4
+
5
+ - `Reactor`
6
+ - `#running?`: Return `false` if the Reactor thread is dead.
7
+ - Added `#on_error`, for exception handling callbacks.
8
+ - All tasks can now receive arguments.
9
+
3
10
  ## Version 0.1.0.beta3 _(August 20, 2014)_
4
11
 
5
12
  - `Connection::TLS#socket_accept`: Return `nil` on error.
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <table>
4
4
  <tr>
5
5
  <th>Version</th>
6
- <td>0.1.0.beta2</td>
6
+ <td>0.1.0.beta4</td>
7
7
  </tr>
8
8
  <tr>
9
9
  <th>Github page</th>
@@ -140,6 +140,7 @@ class Reactor
140
140
  @thread = nil
141
141
  @tasks = Tasks.new
142
142
 
143
+ @error_handlers = Tasks.new
143
144
  @shutdown_tasks = Tasks.new
144
145
  @done_signal = ::Queue.new
145
146
  end
@@ -278,7 +279,7 @@ class Reactor
278
279
  # @return [Bool]
279
280
  # `true` if the {Reactor} is {#run running}, `false` otherwise.
280
281
  def running?
281
- !!thread
282
+ thread && thread.alive?
282
283
  end
283
284
 
284
285
  # Stops the {Reactor} {#run loop} {#schedule as soon as possible}.
@@ -305,10 +306,18 @@ class Reactor
305
306
  block.call if block_given?
306
307
 
307
308
  loop do
308
- @tasks.call
309
+ begin
310
+ @tasks.call
311
+ rescue => e
312
+ @error_handlers.call( e )
313
+ end
309
314
  break if @stop
310
315
 
311
- process_connections
316
+ begin
317
+ process_connections
318
+ rescue => e
319
+ @error_handlers.call( e )
320
+ end
312
321
  break if @stop
313
322
 
314
323
  @ticks += 1
@@ -337,7 +346,11 @@ class Reactor
337
346
  fail_if_running
338
347
 
339
348
  Thread.new do
340
- run(&block)
349
+ begin
350
+ run(&block)
351
+ rescue => e
352
+ @error_handlers.call( e )
353
+ end
341
354
  end
342
355
 
343
356
  sleep 0.1 while !running?
@@ -372,6 +385,17 @@ class Reactor
372
385
  end
373
386
  end
374
387
 
388
+ # @param [Block] block
389
+ # Passes exceptions raised in the Reactor {#thread} to a
390
+ # {Tasks::Persistent task}.
391
+ #
392
+ # @raise (see #fail_if_not_running)
393
+ def on_error( &block )
394
+ fail_if_not_running
395
+ @error_handlers << Tasks::Persistent.new( &block )
396
+ nil
397
+ end
398
+
375
399
  # @param [Block] block
376
400
  # Schedules a {Tasks::Persistent task} to be run at each tick.
377
401
  #
@@ -92,8 +92,8 @@ class Tasks
92
92
  # {Base#call Calls} all tasks.
93
93
  #
94
94
  # @return [Tasks] `self`
95
- def call
96
- @tasks.dup.each(&:call)
95
+ def call( *args )
96
+ @tasks.dup.each { |t| t.call *args }
97
97
  self
98
98
  end
99
99
 
@@ -26,10 +26,10 @@ class Base
26
26
  @task = task
27
27
  end
28
28
 
29
- # Calls the {#initialize configured} task and passes `self` to it.
29
+ # Calls the {#initialize configured} task and passes `args` and self` to it.
30
30
  #
31
31
  # @abstract
32
- def call
32
+ def call( *args )
33
33
  fail NotImplementedError
34
34
  end
35
35
 
@@ -48,8 +48,8 @@ class Base
48
48
 
49
49
  private
50
50
 
51
- def call_task
52
- @task.call self
51
+ def call_task( *args )
52
+ @task.call *([self] + args)
53
53
  end
54
54
 
55
55
  end
@@ -22,10 +22,10 @@ class Delayed < Periodic
22
22
  # @return [Object, nil]
23
23
  # Return value of the configured task or `nil` if it's not
24
24
  # {#interval time} yet.
25
- def call
25
+ def call( *args )
26
26
  return if !call?
27
27
 
28
- call_task.tap { done }
28
+ call_task( *args ).tap { done }
29
29
  end
30
30
 
31
31
  end
@@ -19,8 +19,8 @@ class OneOff < Base
19
19
  #
20
20
  # @return [Object]
21
21
  # Return value of the task.
22
- def call
23
- call_task.tap { done }
22
+ def call( *args )
23
+ call_task( *args ).tap { done }
24
24
  end
25
25
 
26
26
  end
@@ -36,11 +36,11 @@ class Periodic < Persistent
36
36
  # @return [Object, nil]
37
37
  # Return value of the configured task or `nil` if it's not
38
38
  # {#interval time} yet.
39
- def call
39
+ def call( *args )
40
40
  return if !call?
41
41
  calculate_next
42
42
 
43
- super
43
+ super( *args )
44
44
  end
45
45
 
46
46
  private
@@ -20,8 +20,8 @@ class Persistent < Base
20
20
  #
21
21
  # @return [Object]
22
22
  # Return value of the task.
23
- def call
24
- call_task
23
+ def call( *args )
24
+ call_task( *args )
25
25
  end
26
26
 
27
27
  end
@@ -9,7 +9,7 @@
9
9
  module Arachni
10
10
  class Reactor
11
11
 
12
- VERSION = '0.1.0.beta3'
12
+ VERSION = '0.1.0.beta4'
13
13
 
14
14
  end
15
15
  end
@@ -49,6 +49,21 @@ describe Arachni::Reactor::Tasks::Delayed do
49
49
  task.should receive(:done)
50
50
  task.call while called < 1
51
51
  end
52
+
53
+ context 'when arguments have been provided' do
54
+ it 'passes them to the task' do
55
+ called = nil
56
+ task = described_class.new( interval ) do |_, s1, s2|
57
+ called = [s1, s2]
58
+ end
59
+
60
+ list << task
61
+
62
+ task.call( :stuff1, :stuff2 ) while !called
63
+
64
+ called.should == [:stuff1, :stuff2]
65
+ end
66
+ end
52
67
  end
53
68
  end
54
69
  end
@@ -47,5 +47,20 @@ describe Arachni::Reactor::Tasks::OneOff do
47
47
  task.should receive(:done)
48
48
  task.call
49
49
  end
50
+
51
+ context 'when arguments have been provided' do
52
+ it 'passes them to the task' do
53
+ got = nil
54
+ callable = proc do |_, arg|
55
+ got = arg
56
+ end
57
+
58
+ task = described_class.new(&callable)
59
+ list << task
60
+
61
+ task.call :stuff
62
+ got.should == :stuff
63
+ end
64
+ end
50
65
  end
51
66
  end
@@ -36,5 +36,20 @@ describe Arachni::Reactor::Tasks::Periodic do
36
36
  (Time.now - time).round(2).should == 1.25
37
37
  end
38
38
  end
39
+
40
+ context 'when arguments have been provided' do
41
+ it 'passes them to the task' do
42
+ called = nil
43
+ task = described_class.new( interval ) do |_, s1, s2|
44
+ called = [s1, s2]
45
+ end
46
+
47
+ list << task
48
+
49
+ task.call( :stuff1, :stuff2 ) while !called
50
+
51
+ called.should == [:stuff1, :stuff2]
52
+ end
53
+ end
39
54
  end
40
55
  end
@@ -35,5 +35,20 @@ describe Arachni::Reactor::Tasks::Persistent do
35
35
 
36
36
  task.call
37
37
  end
38
+
39
+ context 'when arguments have been provided' do
40
+ it 'passes them to the task' do
41
+ got = nil
42
+ callable = proc do |_, arg|
43
+ got = arg
44
+ end
45
+
46
+ task = described_class.new(&callable)
47
+ list << task
48
+
49
+ task.call :stuff
50
+ got.should == :stuff
51
+ end
52
+ end
38
53
  end
39
54
  end
@@ -132,5 +132,24 @@ describe Arachni::Reactor::Tasks do
132
132
  it 'returns self' do
133
133
  subject.call.should == subject
134
134
  end
135
+
136
+ context 'when arguments have been provided' do
137
+ it 'passes them to the tasks' do
138
+ called_one = nil
139
+ called_two = nil
140
+
141
+ subject << described_class::Persistent.new do |_, arg|
142
+ called_one = arg
143
+ end
144
+ subject << described_class::Persistent.new do |_, arg|
145
+ called_two = arg
146
+ end
147
+
148
+ subject.call( :stuff )
149
+
150
+ called_one.should == :stuff
151
+ called_two.should == :stuff
152
+ end
153
+ end
135
154
  end
136
155
  end
@@ -198,6 +198,33 @@ shared_examples_for 'Arachni::Reactor' do
198
198
  end
199
199
  end
200
200
 
201
+ describe '#on_error' do
202
+ it 'sets a task to be passed raised exceptions' do
203
+ run_reactor_in_thread
204
+
205
+ e = nil
206
+ subject.on_error do |_, error|
207
+ e = error
208
+ end
209
+
210
+ subject.next_tick do
211
+ raise
212
+ end
213
+
214
+ sleep 0.1 while !e
215
+
216
+ e.should be_kind_of RuntimeError
217
+ end
218
+
219
+ context 'when the reactor is not running' do
220
+ it "raises #{klass::Error::NotRunning}" do
221
+ expect do
222
+ subject.next_tick{}
223
+ end.to raise_error klass::Error::NotRunning
224
+ end
225
+ end
226
+ end
227
+
201
228
  describe '#on_shutdown' do
202
229
  it 'calls the given blocks during shutdown' do
203
230
  subject.run_in_thread
@@ -483,6 +510,25 @@ shared_examples_for 'Arachni::Reactor' do
483
510
  subject.should_not be_running
484
511
  end
485
512
  end
513
+
514
+ context 'when the reactor thread has been killed' do
515
+ it 'returns false' do
516
+ run_reactor_in_thread
517
+
518
+ Timeout.timeout 10 do
519
+ sleep 0.1 while !subject.running?
520
+ end
521
+
522
+ subject.should be_running
523
+ subject.thread.kill
524
+
525
+ Timeout.timeout 10 do
526
+ sleep 0.1 while subject.thread.alive?
527
+ end
528
+
529
+ subject.should_not be_running
530
+ end
531
+ end
486
532
  end
487
533
 
488
534
  describe '#stop' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arachni-reactor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta3
4
+ version: 0.1.0.beta4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tasos Laskos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-20 00:00:00.000000000 Z
11
+ date: 2014-09-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  Arachni::Reactor is a simple, lightweight, pure-Ruby implementation of the Reactor