pigeon 0.8.0 → 0.9.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.
data/Rakefile CHANGED
@@ -28,13 +28,3 @@ end
28
28
  task :test => :check_dependencies
29
29
 
30
30
  task :default => :test
31
-
32
- require 'rake/rdoctask'
33
- Rake::RDocTask.new do |rdoc|
34
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
35
-
36
- rdoc.rdoc_dir = 'rdoc'
37
- rdoc.title = "pigeon #{version}"
38
- rdoc.rdoc_files.include('README*')
39
- rdoc.rdoc_files.include('lib/**/*.rb')
40
- end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.0
1
+ 0.9.0
data/lib/pigeon/engine.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'eventmachine'
2
2
  require 'socket'
3
+ require 'fiber'
3
4
 
4
5
  class Pigeon::Engine
5
6
  # == Submodules ===========================================================
@@ -23,6 +24,7 @@ class Pigeon::Engine
23
24
  :boolean => true
24
25
  option_accessor :debug,
25
26
  :boolean => true
27
+ option_accessor :log_rotation
26
28
  option_accessor :engine_log_name,
27
29
  :default => 'engine.log'
28
30
  option_accessor :engine_logger
@@ -44,6 +46,7 @@ class Pigeon::Engine
44
46
  :default => false
45
47
 
46
48
  attr_reader :id
49
+ attr_reader :state
47
50
 
48
51
  # == Constants ============================================================
49
52
 
@@ -53,6 +56,12 @@ class Pigeon::Engine
53
56
  after_start
54
57
  before_stop
55
58
  after_stop
59
+ before_resume
60
+ after_resume
61
+ before_standby
62
+ after_standby
63
+ before_shutdown
64
+ after_shutdown
56
65
  ].collect(&:to_sym).freeze
57
66
 
58
67
  # == Class Methods ========================================================
@@ -166,6 +175,14 @@ class Pigeon::Engine
166
175
  # No such process exception
167
176
  pid = nil
168
177
  end
178
+
179
+ begin
180
+ while (Process.kill(0, pid))
181
+ sleep(1)
182
+ end
183
+ rescue Errno::ESRCH
184
+ # No such process, already terminated
185
+ end
169
186
 
170
187
  pid_file.remove!
171
188
  end
@@ -200,7 +217,7 @@ class Pigeon::Engine
200
217
  f = File.open(File.expand_path(self.engine_log_name, self.log_dir), 'a')
201
218
  f.sync = true
202
219
 
203
- Pigeon::Logger.new(f)
220
+ Pigeon::Logger.new(f, self.log_rotation)
204
221
  end
205
222
  end
206
223
 
@@ -210,7 +227,7 @@ class Pigeon::Engine
210
227
  f = File.open(File.expand_path(self.query_log_name, self.log_dir), 'a')
211
228
  f.sync = true
212
229
 
213
- Pigeon::Logger.new(f)
230
+ Pigeon::Logger.new(f, self.log_rotation)
214
231
  end
215
232
  end
216
233
 
@@ -243,20 +260,22 @@ class Pigeon::Engine
243
260
  def initialize(options = nil)
244
261
  @id = Pigeon::Support.unique_id
245
262
 
246
- @options = options || { }
263
+ wrap_chain(:initialize) do
264
+ @options = options || { }
247
265
 
248
- @task_lock = Mutex.new
249
- @task_locks = { }
266
+ @task_lock = Mutex.new
267
+ @task_locks = { }
250
268
 
251
- @task_register_lock = Mutex.new
252
- @registered_tasks = { }
269
+ @task_register_lock = Mutex.new
270
+ @registered_tasks = { }
253
271
 
254
- self.logger ||= self.engine_logger
255
- self.logger.level = Pigeon::Logger::DEBUG if (self.debug?)
272
+ self.logger ||= self.engine_logger
273
+ self.logger.level = Pigeon::Logger::DEBUG if (self.debug?)
256
274
 
257
- @dispatcher = { }
275
+ @dispatcher = { }
258
276
 
259
- run_chain(:after_initialize)
277
+ @state = :initialized
278
+ end
260
279
  end
261
280
 
262
281
  # Returns the hostname of the system this engine is running on.
@@ -269,15 +288,15 @@ class Pigeon::Engine
269
288
  def run
270
289
  assign_process_name!
271
290
 
272
- run_chain(:before_start)
273
-
274
- STDOUT.sync = true
291
+ wrap_chain(:start) do
292
+ STDOUT.sync = true
275
293
 
276
- logger.info("Engine \##{id} Running")
277
-
278
- run_chain(:after_start)
294
+ logger.info("Engine \##{id} Running")
279
295
 
280
- switch_to_effective_user! if (self.class.user)
296
+ switch_to_effective_user! if (self.class.user)
297
+
298
+ @state = :running
299
+ end
281
300
  end
282
301
 
283
302
  # Used to periodically execute a task or block. When giving a task name,
@@ -339,11 +358,10 @@ class Pigeon::Engine
339
358
  # Shuts down the engine. Will also trigger the before_stop and after_stop
340
359
  # events.
341
360
  def terminate
342
- run_chain(:before_stop)
343
-
344
- EventMachine.stop_event_loop
345
-
346
- run_chain(:after_stop)
361
+ wrap_chain(:stop) do
362
+ EventMachine.stop_event_loop
363
+ @state = :terminated
364
+ end
347
365
  end
348
366
 
349
367
  # Used to dispatch a block for immediate processing on a background thread.
@@ -359,6 +377,43 @@ class Pigeon::Engine
359
377
  EventMachine.next_tick(&block)
360
378
  end
361
379
  end
380
+
381
+ def resume!
382
+ case (@state)
383
+ when :running
384
+ # Ignored since already running.
385
+ when :terminated
386
+ # Invalid operation, should produce error.
387
+ else
388
+ wrap_chain(:resume) do
389
+ @state = :running
390
+ end
391
+ end
392
+ end
393
+
394
+ def standby!
395
+ case (@state)
396
+ when :standby
397
+ # Already in standby state, ignored.
398
+ when :terminated
399
+ # Invalid operation, should produce error.
400
+ else
401
+ wrap_chain(:standby) do
402
+ @state = :standby
403
+ end
404
+ end
405
+ end
406
+
407
+ def shutdown!
408
+ case (@state)
409
+ when :terminated
410
+ # Already terminated, ignored.
411
+ else
412
+ wrap_chain(:shutdown) do
413
+ self.terminate
414
+ end
415
+ end
416
+ end
362
417
 
363
418
  class << self
364
419
  CHAINS.each do |chain_name|
@@ -377,14 +432,8 @@ class Pigeon::Engine
377
432
  end
378
433
  end
379
434
 
380
- def run_chain(chain_name, instance)
381
- chain = instance_variable_get(:"@_#{chain_name}_chain")
382
-
383
- return unless (chain)
384
-
385
- chain.each do |proc|
386
- instance.instance_eval(&proc)
387
- end
435
+ def chain_procs(chain_name)
436
+ instance_variable_get(:"@_#{chain_name}_chain")
388
437
  end
389
438
  end
390
439
 
@@ -421,8 +470,42 @@ class Pigeon::Engine
421
470
  end
422
471
 
423
472
  protected
473
+ def wrap_chain(chain_name)
474
+ Fiber.new do
475
+ run_chain(:"before_#{chain_name}")
476
+ yield if (block_given?)
477
+ run_chain(:"after_#{chain_name}")
478
+ end.resume
479
+ end
480
+
424
481
  def run_chain(chain_name)
425
- self.class.run_chain(chain_name, self)
482
+ callbacks = { }
483
+ fiber = Fiber.current
484
+
485
+ if (procs = self.class.chain_procs(chain_name))
486
+ procs.each do |proc|
487
+ case (proc.arity)
488
+ when 1
489
+ callback = lambda {
490
+ callbacks.delete(callback)
491
+
492
+ if (callbacks.empty?)
493
+ fiber.resume
494
+ end
495
+ }
496
+
497
+ callbacks[callback] = true
498
+
499
+ instance_exec(callback, &proc)
500
+ else
501
+ instance_eval(&proc)
502
+ end
503
+ end
504
+
505
+ if (callbacks.any?)
506
+ Fiber.yield
507
+ end
508
+ end
426
509
  end
427
510
 
428
511
  def switch_to_effective_user!
@@ -46,43 +46,47 @@ class Pigeon::Launcher
46
46
  end
47
47
 
48
48
  def run(pid)
49
- puts "#{@engine.name} now running. [%d]" % pid
50
- puts "Use ^C to terminate."
49
+ log "#{@engine.name} now running. [%d]" % pid
50
+ log "Use ^C to terminate."
51
51
  end
52
52
 
53
53
  def start(pid)
54
- puts "#{@engine.name} now running. [%d]" % pid
54
+ log "#{@engine.name} now running. [%d]" % pid
55
55
  end
56
56
 
57
57
  def stop(pid)
58
58
  if (pid)
59
- puts "#{@engine.name} shut down. [%d]" % pid
59
+ log "#{@engine.name} shut down. [%d]" % pid
60
60
  else
61
- puts "#{@engine.name} was not running."
61
+ log "#{@engine.name} was not running."
62
62
  end
63
63
  end
64
64
 
65
65
  def status(pid)
66
66
  if (pid)
67
- puts "#{@engine.name} running. [%d]" % pid
67
+ log "#{@engine.name} running. [%d]" % pid
68
68
  else
69
- puts "#{@engine.name} is not running."
69
+ log "#{@engine.name} is not running."
70
70
  end
71
71
  end
72
72
 
73
73
  def restart(pid, old_pid)
74
74
  if (old_pid)
75
- puts "#{@engine.name} terminated. [%d]" % old_pid
75
+ log "#{@engine.name} terminated. [%d]" % old_pid
76
76
  end
77
77
 
78
- puts "#{@engine.name} now running. [%d]" % pid
78
+ log "#{@engine.name} now running. [%d]" % pid
79
79
  end
80
80
 
81
81
  def shutdown(pid)
82
- puts "Shutting down."
82
+ log "Shutting down."
83
83
  end
84
84
 
85
85
  def usage
86
- puts "Usage: #{File.basename($0)} [start|stop|restart|status|run]"
86
+ log "Usage: #{File.basename($0)} [start|stop|restart|status|run]"
87
+ end
88
+
89
+ def log(message)
90
+ puts message
87
91
  end
88
92
  end
data/lib/pigeon.rb CHANGED
@@ -19,4 +19,5 @@ end
19
19
  # issue where requiring it later causes a run-time Interrupt exception.
20
20
  require 'pigeon/logger'
21
21
 
22
+ # The fastthread library is not essential, so loading errors can be ignored.
22
23
  require 'fastthread' rescue nil
data/pigeon.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "pigeon"
8
- s.version = "0.8.0"
8
+ s.version = "0.9.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["tadman"]
12
- s.date = "2012-04-04"
12
+ s.date = "2012-10-15"
13
13
  s.description = "Pigeon is a simple way to get started building an EventMachine engine that's intended to run as a background job."
14
14
  s.email = "github@tadman.ca"
15
15
  s.extra_rdoc_files = [
@@ -52,7 +52,7 @@ Gem::Specification.new do |s|
52
52
  ]
53
53
  s.homepage = "http://github.com/twg/pigeon"
54
54
  s.require_paths = ["lib"]
55
- s.rubygems_version = "1.8.17"
55
+ s.rubygems_version = "1.8.24"
56
56
  s.summary = "Simple daemonized EventMachine engine framework with plug-in support"
57
57
 
58
58
  if s.respond_to? :specification_version then
data/test/helper.rb CHANGED
@@ -8,10 +8,10 @@ require 'timeout'
8
8
 
9
9
  require 'rubygems'
10
10
 
11
- if (Gem.available?('eventmachine'))
11
+ begin
12
12
  gem 'eventmachine'
13
- else
14
- raise "EventMachine gem is not installed."
13
+ rescue => e
14
+ raise "EventMachine gem is not installed or could not be loaded: [#{e.class}] #{e}"
15
15
  end
16
16
 
17
17
  require 'pigeon'
@@ -37,37 +37,30 @@ class Test::Unit::TestCase
37
37
 
38
38
  def engine
39
39
  exception = nil
40
+
41
+ Pigeon::Engine.launch do |new_engine|
42
+ @engine = new_engine
40
43
 
41
- @engine_thread = Thread.new do
42
- Thread.abort_on_exception = true
43
-
44
- # Create a thread for the engine to run on
45
- begin
46
- Pigeon::Engine.launch do |new_engine|
47
- @engine = new_engine
48
-
49
- Thread.new do
50
- # Execute the test code in a separate thread to avoid blocking
51
- # the EventMachine loop.
52
- begin
53
- yield
54
- rescue Object => exception
55
- ensure
56
- begin
57
- @engine.terminate
58
- rescue Object
59
- # Shutting down may trigger an exception from time to time
60
- # if the engine itself has failed.
61
- end
62
- end
44
+ # Execute the test code in a separate thread to avoid blocking
45
+ # the EventMachine loop.
46
+ Thread.new do
47
+ begin
48
+ Thread.abort_on_exception = true
49
+ yield
50
+ rescue Object => exception
51
+ ensure
52
+ begin
53
+ # Regardless what happened, always terminate the engine.
54
+ @engine.terminate
55
+ rescue Object => e
56
+ # Shutting down may trigger an exception from time to time
57
+ # if the engine itself has failed.
58
+ STDERR.puts("Exception: [#{e.class}] #{e}")
63
59
  end
64
60
  end
65
- rescue Object => exception
66
61
  end
67
62
  end
68
63
 
69
- @engine_thread.join
70
-
71
64
  if (exception)
72
65
  raise exception
73
66
  end
@@ -11,15 +11,26 @@ class PigeonQueueTest < Test::Unit::TestCase
11
11
  end
12
12
 
13
13
  def test_queue_cycling
14
- queue = Pigeon::Queue.new
14
+ engine do
15
+ queue = Pigeon::Queue.new
16
+
17
+ task = Pigeon::Task.new
18
+
19
+ queue << task
20
+
21
+ assert_eventually(1) do
22
+ !queue.empty?
23
+ end
15
24
 
16
- task = Pigeon::Task.new
25
+ assert_equal 1, queue.length
26
+ assert !queue.empty?
17
27
 
18
- queue << task
28
+ found_task = queue.pop
19
29
 
20
- assert_equal 1, queue.length
21
- assert !queue.empty?
30
+ assert_equal task, found_task
22
31
 
23
- found_task = queue.pop
32
+ assert_equal 0, queue.length
33
+ assert queue.empty?
34
+ end
24
35
  end
25
36
  end
@@ -55,6 +55,22 @@ class CallbackTestEngine < Pigeon::Engine
55
55
  end
56
56
  end
57
57
 
58
+ class ShutdownCallbackTestEngine < Pigeon::Engine
59
+ attr_accessor :callbacks
60
+
61
+ after_start do
62
+ @callbacks = [ ]
63
+ end
64
+
65
+ before_shutdown do |callback|
66
+ @callbacks << callback
67
+ end
68
+
69
+ before_shutdown do |callback|
70
+ @callbacks << callback
71
+ end
72
+ end
73
+
58
74
  class TestPigeonEngine < Test::Unit::TestCase
59
75
  def test_default_options
60
76
  assert TestEngine.engine_logger
@@ -173,4 +189,43 @@ class TestPigeonEngine < Test::Unit::TestCase
173
189
 
174
190
  assert_equal nil, running_pid
175
191
  end
192
+
193
+ def test_shutdown_engine_with_blocking_callback
194
+ e = nil
195
+
196
+ Thread.new do
197
+ Thread.abort_on_exception = true
198
+
199
+ ShutdownCallbackTestEngine.launch do |_e|
200
+ e = _e
201
+ end
202
+ end
203
+
204
+ assert_eventually(5) do
205
+ e
206
+ end
207
+
208
+ assert e, "Engine variable was not bound"
209
+ assert_equal [ ], e.callbacks
210
+
211
+ assert_eventually(5) do
212
+ e.state == :running
213
+ end
214
+
215
+ e.shutdown!
216
+
217
+ assert e.callbacks
218
+ assert !e.callbacks.empty?
219
+ assert_equal :running, e.state
220
+
221
+ assert_equal 2, e.callbacks.length
222
+
223
+ e.callbacks[0].call
224
+
225
+ assert_equal :running, e.state
226
+
227
+ e.callbacks[1].call
228
+
229
+ assert_equal :terminated, e.state
230
+ end
176
231
  end
@@ -1,5 +1,11 @@
1
1
  require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
2
2
 
3
+ class Pigeon::Launcher
4
+ def log(*args)
5
+ # Disabled for testing.
6
+ end
7
+ end
8
+
3
9
  class PigeonLauncherTest < Test::Unit::TestCase
4
10
  def test_default_launcher
5
11
  pid = Pigeon::Launcher.launch
@@ -3,6 +3,7 @@ require File.expand_path(File.join(*%w[ .. helper ]), File.dirname(__FILE__))
3
3
  class PigeonProcessorTest < Test::Unit::TestCase
4
4
  class TaggedTask < Pigeon::Task
5
5
  attr_accessor :tag
6
+ attr_reader :last_task
6
7
 
7
8
  def initialize(tag, options = nil)
8
9
  super(options)
@@ -37,29 +38,36 @@ class PigeonProcessorTest < Test::Unit::TestCase
37
38
  end
38
39
 
39
40
  def test_simple_filter
40
- queue = Pigeon::Queue.new
41
+ engine do
42
+ queue = Pigeon::Queue.new
41
43
 
42
- processor = Pigeon::Processor.new(queue) do |task|
43
- (task.tag % 2) == 1
44
- end
44
+ processor = Pigeon::Processor.new(queue) do |task|
45
+ (task.tag % 2) == 1
46
+ end
45
47
 
46
- assert_equal false, processor.task?
48
+ assert_equal false, processor.task?
47
49
 
48
- queue << TaggedTask.new(0)
50
+ queue << TaggedTask.new(0)
49
51
 
50
- assert_equal false, processor.task?
51
- assert_equal 1, queue.length
52
+ assert_eventually(1) do
53
+ queue.length == 1
54
+ end
55
+
56
+ assert_equal false, processor.task?
57
+ assert_equal 1, queue.length
52
58
 
53
- queue << TaggedTask.new(1)
59
+ queue << TaggedTask.new(1)
54
60
 
55
- assert_equal true, processor.task?
56
- assert_equal 1, queue.length
61
+ assert_eventually(1) do
62
+ queue.length == 1
63
+ end
64
+
65
+ assert_equal 1, queue.length
57
66
 
58
- assert_eventually(5) do
59
- !processor.task?
67
+ assert_eventually(5) do
68
+ !processor.task?
69
+ end
60
70
  end
61
-
62
- assert_equal 1, queue.length
63
71
  end
64
72
 
65
73
  def test_on_backlog
@@ -137,6 +145,10 @@ class PigeonProcessorTest < Test::Unit::TestCase
137
145
  queue << TaggedTask.new(n)
138
146
  end
139
147
 
148
+ assert_eventually(2) do
149
+ queue.length == count
150
+ end
151
+
140
152
  assert_equal count, queue.length
141
153
 
142
154
  processors = (0..9).to_a.collect do
@@ -53,12 +53,13 @@ class PigeonSchedulerTest < Test::Unit::TestCase
53
53
 
54
54
  def test_add
55
55
  queue = Pigeon::Queue.new
56
-
57
56
  scheduler = Pigeon::Scheduler.new(queue)
57
+
58
+ assert scheduler.processors.length > 0
58
59
 
59
60
  count = 1000
60
-
61
61
  backlog = [ ]
62
+
62
63
  count.times do |n|
63
64
  scheduler.add(TaggedTask.new(n * 2 + 1))
64
65
  backlog << TaggedTask.new(n * 2)
@@ -66,8 +67,6 @@ class PigeonSchedulerTest < Test::Unit::TestCase
66
67
 
67
68
  scheduler.add(backlog)
68
69
 
69
- assert !queue.empty?
70
-
71
70
  assert_eventually(5) do
72
71
  queue.empty?
73
72
  end
@@ -44,35 +44,27 @@ class FailingTask < Pigeon::Task
44
44
  end
45
45
 
46
46
  class PigeonTaskTest < Test::Unit::TestCase
47
- def setup
48
- @engine = Pigeon::Engine.new
49
-
50
- Pigeon::Engine.register_engine(@engine)
51
- end
52
-
53
- def teardown
54
- Pigeon::Engine.unregister_engine(@engine)
55
- end
56
-
57
47
  def test_empty_task
58
- task = Pigeon::Task.new
48
+ engine do
49
+ task = Pigeon::Task.new
59
50
 
60
- reported = 0
51
+ reported = 0
61
52
 
62
- task.run! do
63
- reported = 1
64
- end
53
+ task.run! do
54
+ reported = 1
55
+ end
65
56
 
66
- assert_eventually(5) do
67
- task.finished? and reported > 0
68
- end
57
+ assert_eventually(5) do
58
+ task.finished? and reported > 0
59
+ end
69
60
 
70
- assert_equal 1, reported
71
- assert_equal :finished, task.state
61
+ assert_equal 1, reported
62
+ assert_equal :finished, task.state
72
63
 
73
- assert_equal nil, task.exception
64
+ assert_equal nil, task.exception
74
65
 
75
- assert_equal @engine.object_id, task.engine.object_id
66
+ assert_equal @engine.object_id, task.engine.object_id
67
+ end
76
68
  end
77
69
 
78
70
  def test_alternate_engine
@@ -83,61 +75,65 @@ class PigeonTaskTest < Test::Unit::TestCase
83
75
  end
84
76
 
85
77
  def test_example_task
86
- task = ExampleTask.new
87
-
88
- callbacks = [ ]
89
-
90
- task.run! do |state|
91
- callbacks << state
78
+ engine do
79
+ task = ExampleTask.new
80
+
81
+ callbacks = [ ]
82
+
83
+ task.run! do |state|
84
+ callbacks << state
85
+ end
86
+
87
+ assert_eventually(5) do
88
+ task.finished?
89
+ end
90
+
91
+ assert_equal nil, task.exception
92
+
93
+ assert_equal :finished, task.state
94
+
95
+ expected_triggers = [
96
+ :after_initialized,
97
+ :initialized,
98
+ :state1,
99
+ :state2,
100
+ :state3,
101
+ :state4,
102
+ :finished,
103
+ :after_finished
104
+ ]
105
+
106
+ assert_equal expected_triggers, task.triggers
107
+
108
+ expected_callbacks = [
109
+ :initialized,
110
+ :state1,
111
+ :state2,
112
+ :state3,
113
+ :state4,
114
+ :finished
115
+ ]
116
+
117
+ assert_equal expected_callbacks, callbacks
92
118
  end
93
-
94
- assert_eventually(5) do
95
- task.finished?
96
- end
97
-
98
- assert_equal nil, task.exception
99
-
100
- assert_equal :finished, task.state
101
-
102
- expected_triggers = [
103
- :after_initialized,
104
- :initialized,
105
- :state1,
106
- :state2,
107
- :state3,
108
- :state4,
109
- :finished,
110
- :after_finished
111
- ]
112
-
113
- assert_equal expected_triggers, task.triggers
114
-
115
- expected_callbacks = [
116
- :initialized,
117
- :state1,
118
- :state2,
119
- :state3,
120
- :state4,
121
- :finished
122
- ]
123
-
124
- assert_equal expected_callbacks, callbacks
125
119
  end
126
120
 
127
121
  def test_failing_task
128
- task = FailingTask.new
129
-
130
- reported = false
131
-
132
- task.run! do
133
- reported = true
134
- end
135
-
136
- assert_eventually(5) do
137
- task.failed? and reported
138
- end
122
+ engine do
123
+ task = FailingTask.new
124
+
125
+ reported = false
126
+
127
+ task.run! do
128
+ reported = true
129
+ end
130
+
131
+ assert_eventually(5) do
132
+ task.failed? and reported
133
+ end
139
134
 
140
- assert task.exception?
135
+ assert task.exception?
136
+ end
141
137
  end
142
138
 
143
139
  def test_with_context
@@ -156,19 +152,21 @@ class PigeonTaskTest < Test::Unit::TestCase
156
152
  end
157
153
 
158
154
  def test_block_notification
159
- task = Pigeon::Task.new
155
+ engine do
156
+ task = Pigeon::Task.new
160
157
 
161
- states_triggered = [ ]
158
+ states_triggered = [ ]
162
159
 
163
- task.run! do |state|
164
- states_triggered << state
165
- end
160
+ task.run! do |state|
161
+ states_triggered << state
162
+ end
166
163
 
167
- assert_eventually(5) do
168
- task.finished?
169
- end
164
+ assert_eventually(5) do
165
+ task.finished?
166
+ end
170
167
 
171
- assert_equal [ :initialized, :finished ], states_triggered
168
+ assert_equal [ :initialized, :finished ], states_triggered
169
+ end
172
170
  end
173
171
 
174
172
  def test_priority_order
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pigeon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-04 00:00:00.000000000 Z
12
+ date: 2012-10-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &2152583160 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,12 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2152583160
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  description: Pigeon is a simple way to get started building an EventMachine engine
26
31
  that's intended to run as a background job.
27
32
  email: github@tadman.ca
@@ -83,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
88
  version: '0'
84
89
  requirements: []
85
90
  rubyforge_project:
86
- rubygems_version: 1.8.17
91
+ rubygems_version: 1.8.24
87
92
  signing_key:
88
93
  specification_version: 3
89
94
  summary: Simple daemonized EventMachine engine framework with plug-in support