pigeon 1.0.2 → 1.1.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 +4 -4
- data/.travis.yml +2 -1
- data/LICENSE +1 -1
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/pigeon/engine.rb +31 -25
- data/lib/pigeon/launcher.rb +16 -9
- data/lib/pigeon/option_accessor.rb +46 -38
- data/lib/pigeon/pidfile.rb +7 -4
- data/lib/pigeon/processor.rb +2 -1
- data/lib/pigeon/queue.rb +8 -6
- data/lib/pigeon/scheduler.rb +1 -1
- data/lib/pigeon/support.rb +3 -3
- data/lib/pigeon/task.rb +1 -0
- data/pigeon.gemspec +24 -24
- data/test/helper.rb +20 -5
- data/test/unit/pigeon_backlog_test.rb +3 -3
- data/test/unit/pigeon_dispatcher_test.rb +1 -1
- data/test/unit/pigeon_engine_test.rb +5 -5
- data/test/unit/pigeon_launcher_test.rb +3 -9
- data/test/unit/pigeon_option_accessor_test.rb +4 -4
- data/test/unit/pigeon_processor_test.rb +4 -2
- data/test/unit/pigeon_queue_test.rb +11 -9
- data/test/unit/pigeon_scheduler_test.rb +1 -1
- data/test/unit/pigeon_sorted_array_test.rb +1 -1
- data/test/unit/pigeon_task_test.rb +3 -3
- data/test/unit/pigeon_test.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d553925f3fd1fb650f15aa7c7c060f3a7c43151b
|
4
|
+
data.tar.gz: 89d6307360636edbd6af8e5a06b6b3358af63bd7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82cd662072522d65a24aa4ed0df2709f708d86f2ef2315b3119a45d01f9ac2c2a6135ac2812e9e0b0e39ee495121dcec9cabbbe54a9e0f85c759fe12875418a8
|
7
|
+
data.tar.gz: 1267fc9c55dff84fb2ad1dd1bb4da2dcdf400f52e483288403c4f46515209c9affd97d34fc399dcb96dbc0f4bd3e967a9c944ac8ad28ac6b45766f33e84045d5
|
data/.travis.yml
CHANGED
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2009-
|
1
|
+
Copyright (c) 2009-2017 Scott Tadman, PostageApp, The Working Group Inc.
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -9,8 +9,8 @@ begin
|
|
9
9
|
gem.summary = %Q{Simple daemonized EventMachine engine framework with plug-in support}
|
10
10
|
gem.description = %Q{Pigeon is a simple way to get started building an EventMachine engine that's intended to run as a background job.}
|
11
11
|
gem.email = "github@tadman.ca"
|
12
|
-
gem.homepage = "http://github.com/
|
13
|
-
gem.authors =
|
12
|
+
gem.homepage = "http://github.com/postageapp/pigeon"
|
13
|
+
gem.authors = [ 'Scott Tadman' ]
|
14
14
|
gem.executables = [ ]
|
15
15
|
end
|
16
16
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/lib/pigeon/engine.rb
CHANGED
@@ -18,8 +18,8 @@ class Pigeon::Engine
|
|
18
18
|
# == Properties ===========================================================
|
19
19
|
|
20
20
|
option_accessor :logger
|
21
|
-
|
22
|
-
|
21
|
+
option_writer :name
|
22
|
+
option_writer :pid_file_name
|
23
23
|
option_accessor :foreground,
|
24
24
|
boolean: true
|
25
25
|
option_accessor :debug,
|
@@ -27,10 +27,13 @@ class Pigeon::Engine
|
|
27
27
|
option_accessor :log_rotation
|
28
28
|
option_accessor :engine_log_name,
|
29
29
|
default: 'engine.log'
|
30
|
-
|
30
|
+
option_writer :engine_logger,
|
31
|
+
on: :class
|
32
|
+
option_accessor :engine_logger,
|
33
|
+
on: :instance
|
31
34
|
option_accessor :query_log_name,
|
32
35
|
default: 'query.log'
|
33
|
-
|
36
|
+
option_writer :query_logger
|
34
37
|
option_accessor :try_pid_dirs,
|
35
38
|
default: %w[
|
36
39
|
/var/run
|
@@ -69,12 +72,12 @@ class Pigeon::Engine
|
|
69
72
|
# Returns the human-readable name of this engine. Defaults to the name
|
70
73
|
# of the engine class, but can be replaced to customize a subclass.
|
71
74
|
def self.name
|
72
|
-
@name
|
75
|
+
@name ||= self.to_s.gsub(/::/, ' ')
|
73
76
|
end
|
74
77
|
|
75
78
|
# Returns the custom process name for this engine or nil if not assigned.
|
76
79
|
def self.process_name
|
77
|
-
@process_name
|
80
|
+
@process_name ||= nil
|
78
81
|
end
|
79
82
|
|
80
83
|
# Assigns the process name. This will be applied only when the engine is
|
@@ -87,7 +90,7 @@ class Pigeon::Engine
|
|
87
90
|
# user is required. This will be applied after the engine has been started
|
88
91
|
# and the after_start call has been triggered.
|
89
92
|
def self.user
|
90
|
-
@user
|
93
|
+
@user ||= nil
|
91
94
|
end
|
92
95
|
|
93
96
|
# Assigns the user this process should run as, given a username.
|
@@ -98,7 +101,7 @@ class Pigeon::Engine
|
|
98
101
|
# Returns the name of the PID file to use. The full path to the file
|
99
102
|
# is specified elsewhere.
|
100
103
|
def self.pid_file_name
|
101
|
-
@pid_file_name
|
104
|
+
@pid_file_name ||= self.name.downcase.gsub(/ /, '-') + '.pid'
|
102
105
|
end
|
103
106
|
|
104
107
|
# Returns the full path to the PID file that should be used to track
|
@@ -144,6 +147,14 @@ class Pigeon::Engine
|
|
144
147
|
end
|
145
148
|
|
146
149
|
def self.start(options = nil)
|
150
|
+
if (self.pid_file.running?)
|
151
|
+
if (block_given?)
|
152
|
+
yield(self.pid_file.pid, false)
|
153
|
+
end
|
154
|
+
|
155
|
+
return self.pid_file.pid
|
156
|
+
end
|
157
|
+
|
147
158
|
logger = self.engine_logger
|
148
159
|
|
149
160
|
pid = Pigeon::Support.daemonize(logger) do
|
@@ -154,7 +165,7 @@ class Pigeon::Engine
|
|
154
165
|
|
155
166
|
pid_file.create!(pid)
|
156
167
|
|
157
|
-
yield(pid) if (block_given?)
|
168
|
+
yield(pid, true) if (block_given?)
|
158
169
|
|
159
170
|
pid
|
160
171
|
end
|
@@ -238,7 +249,9 @@ class Pigeon::Engine
|
|
238
249
|
# Returns a handle to the engine currently running, or nil if no engine is
|
239
250
|
# currently active.
|
240
251
|
def self.default_engine
|
241
|
-
@engines
|
252
|
+
@engines ||= [ ]
|
253
|
+
|
254
|
+
@engines[0]
|
242
255
|
end
|
243
256
|
|
244
257
|
# Registers the engine as running. The first engine running will show up
|
@@ -250,6 +263,8 @@ class Pigeon::Engine
|
|
250
263
|
|
251
264
|
# Removes the engine from the list of running engines.
|
252
265
|
def self.unregister_engine(engine)
|
266
|
+
return unless (defined?(@engines))
|
267
|
+
|
253
268
|
@engines.delete(engine)
|
254
269
|
end
|
255
270
|
|
@@ -430,10 +445,9 @@ class Pigeon::Engine
|
|
430
445
|
CHAINS.each do |chain_name|
|
431
446
|
define_method(chain_name) do |&block|
|
432
447
|
chain_iv = :"@_#{chain_name}_chain"
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
448
|
+
|
449
|
+
chain = instance_variable_defined?(chain_iv) && instance_variable_get(chain_iv)
|
450
|
+
|
437
451
|
unless (chain)
|
438
452
|
chain = [ ]
|
439
453
|
instance_variable_set(chain_iv, chain)
|
@@ -444,18 +458,10 @@ class Pigeon::Engine
|
|
444
458
|
end
|
445
459
|
|
446
460
|
def chain_procs(chain_name)
|
447
|
-
|
448
|
-
end
|
449
|
-
end
|
461
|
+
chain_iv = :"@_#{chain_name}_chain"
|
450
462
|
|
451
|
-
|
452
|
-
|
453
|
-
!!self.debug
|
454
|
-
end
|
455
|
-
|
456
|
-
# Returns true if running in the foreground, false otherwise.
|
457
|
-
def foreground?
|
458
|
-
!!self.foreground
|
463
|
+
instance_variable_defined?(chain_iv) and instance_variable_get(chain_iv)
|
464
|
+
end
|
459
465
|
end
|
460
466
|
|
461
467
|
# Registers a task with the engine. The given task will then be included
|
data/lib/pigeon/launcher.rb
CHANGED
@@ -3,16 +3,17 @@ require 'optparse'
|
|
3
3
|
class Pigeon::Launcher
|
4
4
|
# == Class Methods ========================================================
|
5
5
|
|
6
|
-
def self.launch(engine = Pigeon::Engine, *arguments)
|
6
|
+
def self.launch(engine = Pigeon::Engine, *arguments, logging: true)
|
7
7
|
arguments = %w[ start ] if (arguments.empty?)
|
8
8
|
|
9
|
-
new(engine).handle_args(*arguments)
|
9
|
+
new(engine, logging: logging).handle_args(*arguments)
|
10
10
|
end
|
11
11
|
|
12
12
|
# == Instance Methods =====================================================
|
13
13
|
|
14
|
-
def initialize(with_engine = Pigeon::Engine)
|
14
|
+
def initialize(with_engine = Pigeon::Engine, logging: true)
|
15
15
|
@engine = with_engine
|
16
|
+
@logging = !!logging
|
16
17
|
|
17
18
|
yield(self) if (block_given?)
|
18
19
|
end
|
@@ -39,9 +40,9 @@ class Pigeon::Launcher
|
|
39
40
|
begin
|
40
41
|
case (command)
|
41
42
|
when 'start'
|
42
|
-
@engine.start do |pid|
|
43
|
-
yield(pid) if (block_given?)
|
44
|
-
self.start(pid)
|
43
|
+
@engine.start do |pid, launched|
|
44
|
+
yield(pid, launched) if (block_given?)
|
45
|
+
self.start(pid, launched)
|
45
46
|
end
|
46
47
|
when 'stop'
|
47
48
|
@engine.stop do |pid|
|
@@ -79,8 +80,12 @@ class Pigeon::Launcher
|
|
79
80
|
log "Use ^C to terminate."
|
80
81
|
end
|
81
82
|
|
82
|
-
def start(pid)
|
83
|
-
|
83
|
+
def start(pid, launched)
|
84
|
+
if (launched)
|
85
|
+
log "#{@engine.name} now running. [%d]" % pid
|
86
|
+
else
|
87
|
+
log "#{@engine.name} already running. [%d]" % pid
|
88
|
+
end
|
84
89
|
end
|
85
90
|
|
86
91
|
def stop(pid)
|
@@ -116,6 +121,8 @@ class Pigeon::Launcher
|
|
116
121
|
end
|
117
122
|
|
118
123
|
def log(message)
|
119
|
-
|
124
|
+
if (@logging)
|
125
|
+
puts(message)
|
126
|
+
end
|
120
127
|
end
|
121
128
|
end
|
@@ -5,9 +5,9 @@ module Pigeon::OptionAccessor
|
|
5
5
|
# but these defaults can be over-ridden in subclasses and instances
|
6
6
|
# without interference. Optional hash at end of list can be used to set:
|
7
7
|
# * :default => Assigns a default value which is otherwise nil
|
8
|
-
def option_accessor(*args)
|
9
|
-
option_reader(*args)
|
10
|
-
option_writer(*args)
|
8
|
+
def option_accessor(*args, boolean: false, default: nil, on: [ :class, :instance ])
|
9
|
+
option_reader(*args, boolean: boolean, default: default, on: on)
|
10
|
+
option_writer(*args, boolean: boolean, on: on)
|
11
11
|
end
|
12
12
|
|
13
13
|
# Given a list of names, this declares an option reader which works like
|
@@ -18,44 +18,48 @@ module Pigeon::OptionAccessor
|
|
18
18
|
# * :default => Assigns a default value which is otherwise nil
|
19
19
|
# * :boolean => If true, creates an additional name? method and will
|
20
20
|
# convert all assigned values to a boolean true/false.
|
21
|
-
def option_reader(*names)
|
21
|
+
def option_reader(*names, boolean: false, default: nil, on: [ :class, :instance ])
|
22
22
|
names = [ names ].flatten.compact
|
23
|
-
|
23
|
+
on = [ on ].flatten
|
24
24
|
|
25
25
|
names.each do |name|
|
26
26
|
iv = :"@#{name}"
|
27
27
|
|
28
|
-
(class
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
if (on.include?(:class))
|
29
|
+
(class << self; self; end).class_eval do
|
30
|
+
if (boolean)
|
31
|
+
define_method(:"#{name}?") do
|
32
|
+
iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil
|
32
33
|
|
33
|
-
|
34
|
+
!!(iv_value.nil? ? (self.superclass.respond_to?(name) ? self.superclass.send(name) : nil) : iv_value)
|
35
|
+
end
|
34
36
|
end
|
35
|
-
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
define_method(name) do
|
39
|
+
iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil
|
40
|
+
|
41
|
+
iv_value.nil? ? (self.superclass.respond_to?(name) ? self.superclass.send(name) : nil) : iv_value
|
42
|
+
end
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
+
if (on.include?(:instance))
|
47
|
+
define_method(name) do
|
48
|
+
iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil
|
46
49
|
|
47
|
-
|
48
|
-
|
50
|
+
iv_value.nil? ? self.class.send(name) : iv_value
|
51
|
+
end
|
49
52
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
+
if (boolean)
|
54
|
+
define_method(:"#{name}?") do
|
55
|
+
iv_value = instance_variable_defined?(iv) ? instance_variable_get(iv) : nil
|
53
56
|
|
54
|
-
|
57
|
+
!!(iv_value.nil? ? self.class.send(name) : iv_value)
|
58
|
+
end
|
55
59
|
end
|
56
60
|
end
|
57
61
|
|
58
|
-
instance_variable_set(iv,
|
62
|
+
instance_variable_set(iv, default)
|
59
63
|
end
|
60
64
|
end
|
61
65
|
|
@@ -64,15 +68,29 @@ module Pigeon::OptionAccessor
|
|
64
68
|
# defined for a class will propagate down to the instances and subclasses,
|
65
69
|
# but these defaults can be over-ridden in subclasses and instances
|
66
70
|
# without interference.
|
67
|
-
def option_writer(*names)
|
71
|
+
def option_writer(*names, boolean: false, on: [ :class, :instance ])
|
68
72
|
names = [ names ].flatten.compact
|
69
|
-
|
73
|
+
on = [ on ].flatten
|
70
74
|
|
71
75
|
names.each do |name|
|
72
76
|
iv = :"@#{name}"
|
73
77
|
|
74
|
-
(class
|
75
|
-
|
78
|
+
if (on.include?(:class))
|
79
|
+
(class << self; self; end).class_eval do
|
80
|
+
if (boolean)
|
81
|
+
define_method(:"#{name}=") do |value|
|
82
|
+
instance_variable_set(iv, value.nil? ? nil : !!value)
|
83
|
+
end
|
84
|
+
else
|
85
|
+
define_method(:"#{name}=") do |value|
|
86
|
+
instance_variable_set(iv, value)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
if (on.include?(:instance))
|
93
|
+
if (boolean)
|
76
94
|
define_method(:"#{name}=") do |value|
|
77
95
|
instance_variable_set(iv, value.nil? ? nil : !!value)
|
78
96
|
end
|
@@ -82,16 +100,6 @@ module Pigeon::OptionAccessor
|
|
82
100
|
end
|
83
101
|
end
|
84
102
|
end
|
85
|
-
|
86
|
-
if (options[:boolean])
|
87
|
-
define_method(:"#{name}=") do |value|
|
88
|
-
instance_variable_set(iv, value.nil? ? nil : !!value)
|
89
|
-
end
|
90
|
-
else
|
91
|
-
define_method(:"#{name}=") do |value|
|
92
|
-
instance_variable_set(iv, value)
|
93
|
-
end
|
94
|
-
end
|
95
103
|
end
|
96
104
|
end
|
97
105
|
end
|
data/lib/pigeon/pidfile.rb
CHANGED
@@ -20,15 +20,18 @@ class Pigeon::Pidfile
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def running
|
23
|
-
|
23
|
+
_pid = self.pid
|
24
24
|
|
25
|
-
(
|
25
|
+
(_pid and Process.kill(0, _pid)) ? _pid : nil
|
26
26
|
rescue Errno::ESRCH
|
27
27
|
nil
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
31
|
-
File.read(@path)
|
30
|
+
def pid
|
31
|
+
contents = File.read(@path)
|
32
|
+
|
33
|
+
contents and contents.to_i
|
34
|
+
|
32
35
|
rescue Errno::ENOENT
|
33
36
|
nil
|
34
37
|
end
|
data/lib/pigeon/processor.rb
CHANGED
@@ -21,6 +21,7 @@ class Pigeon::Processor
|
|
21
21
|
@id = Pigeon::Support.unique_id
|
22
22
|
@filter = filter
|
23
23
|
@context = context
|
24
|
+
@task = nil
|
24
25
|
|
25
26
|
if (queue)
|
26
27
|
self.queue = queue
|
@@ -32,7 +33,7 @@ class Pigeon::Processor
|
|
32
33
|
# Assigns this processor to a particular queue. If one is already assigned
|
33
34
|
# then the observer callback for that queue will be removed.
|
34
35
|
def queue=(queue)
|
35
|
-
if (@queue)
|
36
|
+
if (defined?(@queue))
|
36
37
|
@queue.remove_processor(self, &@claim)
|
37
38
|
end
|
38
39
|
|
data/lib/pigeon/queue.rb
CHANGED
@@ -88,7 +88,7 @@ class Pigeon::Queue
|
|
88
88
|
set << block
|
89
89
|
end
|
90
90
|
|
91
|
-
|
91
|
+
assign_next_task(filter_name)
|
92
92
|
end
|
93
93
|
|
94
94
|
# Removes references to the callback function specified. Note that the same
|
@@ -198,6 +198,8 @@ class Pigeon::Queue
|
|
198
198
|
|
199
199
|
# Iterates over each of the tasks in the queue.
|
200
200
|
def each
|
201
|
+
tasks = nil
|
202
|
+
|
201
203
|
@filters.synchronize do
|
202
204
|
tasks = @tasks.dup
|
203
205
|
end
|
@@ -243,9 +245,9 @@ class Pigeon::Queue
|
|
243
245
|
|
244
246
|
@tasks -= tasks
|
245
247
|
|
246
|
-
@next_task.each do |
|
247
|
-
if (tasks.include?(@next_task[
|
248
|
-
@next_task[
|
248
|
+
@next_task.keys.each do |_filter_name|
|
249
|
+
if (tasks.include?(@next_task[_filter_name]))
|
250
|
+
@next_task[_filter_name] = nil
|
249
251
|
end
|
250
252
|
end
|
251
253
|
|
@@ -276,9 +278,9 @@ class Pigeon::Queue
|
|
276
278
|
if (task)
|
277
279
|
@tasks.delete(task)
|
278
280
|
|
279
|
-
@next_task.each do |
|
281
|
+
@next_task.each do |_filter_name, next_task|
|
280
282
|
if (task == next_task)
|
281
|
-
@next_task[
|
283
|
+
@next_task[_filter_name] = nil
|
282
284
|
end
|
283
285
|
end
|
284
286
|
end
|
data/lib/pigeon/scheduler.rb
CHANGED
data/lib/pigeon/support.rb
CHANGED
@@ -49,7 +49,7 @@ module Pigeon::Support
|
|
49
49
|
relaunch = false
|
50
50
|
end
|
51
51
|
|
52
|
-
|
52
|
+
_, status = Process.wait2(daemon_pid)
|
53
53
|
|
54
54
|
if (interrupted)
|
55
55
|
logger.info("Supervisor #{Process.pid} received termination signal, shut down child #{daemon_pid}.")
|
@@ -57,7 +57,7 @@ module Pigeon::Support
|
|
57
57
|
|
58
58
|
# A non-zero exit status indicates some sort of error, so the
|
59
59
|
# process will be relaunched after a short delay.
|
60
|
-
relaunch = (
|
60
|
+
relaunch = (status != 0)
|
61
61
|
|
62
62
|
ensure
|
63
63
|
# Reset Signal handler before forking again
|
@@ -86,7 +86,7 @@ module Pigeon::Support
|
|
86
86
|
wfd.close
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
Process.wait2(forked_pid)
|
90
90
|
|
91
91
|
daemon_pid = rfd.readline
|
92
92
|
rfd.close
|
data/lib/pigeon/task.rb
CHANGED
data/pigeon.gemspec
CHANGED
@@ -2,18 +2,18 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: pigeon 1.0
|
5
|
+
# stub: pigeon 1.1.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
|
-
s.name = "pigeon"
|
9
|
-
s.version = "1.0
|
8
|
+
s.name = "pigeon".freeze
|
9
|
+
s.version = "1.1.0"
|
10
10
|
|
11
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
-
s.require_paths = ["lib"]
|
13
|
-
s.authors = ["
|
14
|
-
s.date = "
|
15
|
-
s.description = "Pigeon is a simple way to get started building an EventMachine engine that's intended to run as a background job."
|
16
|
-
s.email = "github@tadman.ca"
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["Scott Tadman".freeze]
|
14
|
+
s.date = "2017-09-22"
|
15
|
+
s.description = "Pigeon is a simple way to get started building an EventMachine engine that's intended to run as a background job.".freeze
|
16
|
+
s.email = "github@tadman.ca".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE",
|
19
19
|
"README.md"
|
@@ -54,29 +54,29 @@ Gem::Specification.new do |s|
|
|
54
54
|
"test/unit/pigeon_task_test.rb",
|
55
55
|
"test/unit/pigeon_test.rb"
|
56
56
|
]
|
57
|
-
s.homepage = "http://github.com/
|
58
|
-
s.rubygems_version = "2.
|
59
|
-
s.summary = "Simple daemonized EventMachine engine framework with plug-in support"
|
57
|
+
s.homepage = "http://github.com/postageapp/pigeon".freeze
|
58
|
+
s.rubygems_version = "2.5.2".freeze
|
59
|
+
s.summary = "Simple daemonized EventMachine engine framework with plug-in support".freeze
|
60
60
|
|
61
61
|
if s.respond_to? :specification_version then
|
62
62
|
s.specification_version = 4
|
63
63
|
|
64
64
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
65
|
-
s.add_runtime_dependency(%q<eventmachine
|
66
|
-
s.add_development_dependency(%q<minitest-reporters
|
67
|
-
s.add_development_dependency(%q<minitest
|
68
|
-
s.add_development_dependency(%q<jeweler
|
65
|
+
s.add_runtime_dependency(%q<eventmachine>.freeze, [">= 0"])
|
66
|
+
s.add_development_dependency(%q<minitest-reporters>.freeze, [">= 0"])
|
67
|
+
s.add_development_dependency(%q<minitest>.freeze, [">= 0"])
|
68
|
+
s.add_development_dependency(%q<jeweler>.freeze, [">= 0"])
|
69
69
|
else
|
70
|
-
s.add_dependency(%q<eventmachine
|
71
|
-
s.add_dependency(%q<minitest-reporters
|
72
|
-
s.add_dependency(%q<minitest
|
73
|
-
s.add_dependency(%q<jeweler
|
70
|
+
s.add_dependency(%q<eventmachine>.freeze, [">= 0"])
|
71
|
+
s.add_dependency(%q<minitest-reporters>.freeze, [">= 0"])
|
72
|
+
s.add_dependency(%q<minitest>.freeze, [">= 0"])
|
73
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
74
74
|
end
|
75
75
|
else
|
76
|
-
s.add_dependency(%q<eventmachine
|
77
|
-
s.add_dependency(%q<minitest-reporters
|
78
|
-
s.add_dependency(%q<minitest
|
79
|
-
s.add_dependency(%q<jeweler
|
76
|
+
s.add_dependency(%q<eventmachine>.freeze, [">= 0"])
|
77
|
+
s.add_dependency(%q<minitest-reporters>.freeze, [">= 0"])
|
78
|
+
s.add_dependency(%q<minitest>.freeze, [">= 0"])
|
79
|
+
s.add_dependency(%q<jeweler>.freeze, [">= 0"])
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
data/test/helper.rb
CHANGED
@@ -8,8 +8,12 @@ module Minitest
|
|
8
8
|
# status code based on test results is okay for the parent process, but
|
9
9
|
# causes friction when using fork within tests. Here it's disabled unless
|
10
10
|
# the process terminating is the parent.
|
11
|
+
class << self
|
12
|
+
undef_method(:autorun)
|
13
|
+
end
|
14
|
+
|
11
15
|
def self.autorun
|
12
|
-
return if (@at_exit_hook_installed)
|
16
|
+
return if (defined?(@at_exit_hook_installed))
|
13
17
|
|
14
18
|
@at_exit_hook_installed = Process.pid
|
15
19
|
|
@@ -51,10 +55,10 @@ class Minitest::Test
|
|
51
55
|
flunk(message || 'assert_timeout timed out')
|
52
56
|
end
|
53
57
|
|
54
|
-
def assert_eventually(time = nil, message = nil
|
58
|
+
def assert_eventually(time = nil, message = nil)
|
55
59
|
start_time = Time.now.to_f
|
56
60
|
|
57
|
-
while (!
|
61
|
+
while (!yield)
|
58
62
|
select(nil, nil, nil, 0.1)
|
59
63
|
|
60
64
|
if (time and (Time.now.to_f - start_time > time))
|
@@ -64,6 +68,7 @@ class Minitest::Test
|
|
64
68
|
end
|
65
69
|
|
66
70
|
def engine
|
71
|
+
@engine = nil
|
67
72
|
exception = nil
|
68
73
|
test_thread = nil
|
69
74
|
|
@@ -79,7 +84,13 @@ class Minitest::Test
|
|
79
84
|
@engine = launched
|
80
85
|
end
|
81
86
|
|
82
|
-
rescue Object =>
|
87
|
+
rescue Object => e
|
88
|
+
# $stderr.puts('[%s] %s' % [ e.class, e ])
|
89
|
+
# $stderr.puts(e.backtrace.join("\n"))
|
90
|
+
|
91
|
+
exception = e
|
92
|
+
|
93
|
+
Thread.current.kill
|
83
94
|
end
|
84
95
|
end
|
85
96
|
|
@@ -90,10 +101,14 @@ class Minitest::Test
|
|
90
101
|
begin
|
91
102
|
while (!@engine or Pigeon::Engine.default_engine != @engine)
|
92
103
|
# Wait impatiently.
|
104
|
+
if (exception)
|
105
|
+
Thread.current.kill
|
106
|
+
end
|
93
107
|
end
|
94
108
|
|
95
109
|
yield(@engine)
|
96
|
-
rescue Object =>
|
110
|
+
rescue Object => e
|
111
|
+
exception = e
|
97
112
|
ensure
|
98
113
|
begin
|
99
114
|
if (EventMachine.reactor_running?)
|
@@ -1,13 +1,13 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class PigeonBacklogTest < Minitest::Test
|
4
4
|
def test_empty_queue
|
5
5
|
queue = Pigeon::Queue.new
|
6
6
|
|
7
7
|
assert queue.empty?
|
8
8
|
assert_equal 0, queue.length
|
9
9
|
|
10
|
-
|
10
|
+
assert_nil queue.pop
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_queue_cycling
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
|
3
3
|
module TestModule
|
4
4
|
def self.included(engine)
|
@@ -76,7 +76,7 @@ class TestPigeonEngine < Minitest::Test
|
|
76
76
|
assert TestEngine.engine_logger
|
77
77
|
assert TestEngine.engine_logger.is_a?(Logger)
|
78
78
|
|
79
|
-
|
79
|
+
assert_nil TestEngine.default_engine
|
80
80
|
end
|
81
81
|
|
82
82
|
def test_example_subclass
|
@@ -104,7 +104,7 @@ class TestPigeonEngine < Minitest::Test
|
|
104
104
|
end
|
105
105
|
|
106
106
|
TestEngine.status do |pid|
|
107
|
-
|
107
|
+
assert_nil pid
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -129,7 +129,7 @@ class TestPigeonEngine < Minitest::Test
|
|
129
129
|
|
130
130
|
assert_equal engine_pid, TestEngine.stop
|
131
131
|
|
132
|
-
|
132
|
+
assert_nil TestEngine.status
|
133
133
|
end
|
134
134
|
|
135
135
|
def test_callbacks
|
@@ -158,7 +158,7 @@ class TestPigeonEngine < Minitest::Test
|
|
158
158
|
end
|
159
159
|
|
160
160
|
CallbackTestEngine.status do |pid|
|
161
|
-
|
161
|
+
assert_nil pid
|
162
162
|
end
|
163
163
|
|
164
164
|
expected_callbacks = [
|
@@ -1,14 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
class Pigeon::Launcher
|
4
|
-
def log(*args)
|
5
|
-
# Disabled for testing.
|
6
|
-
end
|
7
|
-
end
|
1
|
+
require_relative '../helper'
|
8
2
|
|
9
3
|
class PigeonLauncherTest < Minitest::Test
|
10
4
|
def test_default_launcher
|
11
|
-
pid = Pigeon::Launcher.launch
|
5
|
+
pid = Pigeon::Launcher.launch(logging: false)
|
12
6
|
|
13
7
|
assert pid, "PID should be returned from launcher call"
|
14
8
|
assert Pigeon::Engine.running?
|
@@ -19,7 +13,7 @@ class PigeonLauncherTest < Minitest::Test
|
|
19
13
|
end
|
20
14
|
|
21
15
|
def test_triggers
|
22
|
-
launcher = Pigeon::Launcher.new(Pigeon::Engine)
|
16
|
+
launcher = Pigeon::Launcher.new(Pigeon::Engine, logging: false)
|
23
17
|
|
24
18
|
triggered = Hash.new { |h,k| h[k] = [ ] }
|
25
19
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
|
3
3
|
class OptionClass
|
4
4
|
extend Pigeon::OptionAccessor
|
@@ -57,15 +57,15 @@ class PigeonOptionAccessorTest < Minitest::Test
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def test_boolean_option
|
60
|
-
|
60
|
+
assert_nil OptionClass.multi1
|
61
61
|
|
62
62
|
instance = OptionClass.new
|
63
63
|
|
64
64
|
instance.multi1 = false
|
65
65
|
|
66
66
|
assert_equal false, instance.multi1
|
67
|
-
|
67
|
+
assert_nil OptionClass.multi1
|
68
68
|
|
69
|
-
|
69
|
+
assert_nil instance.multi2
|
70
70
|
end
|
71
71
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
|
3
3
|
class PigeonProcessorTest < Minitest::Test
|
4
4
|
class TaggedTask < Pigeon::Task
|
@@ -87,6 +87,8 @@ class PigeonProcessorTest < Minitest::Test
|
|
87
87
|
assert_eventually(5) do
|
88
88
|
queue.empty?
|
89
89
|
end
|
90
|
+
|
91
|
+
assert !processor.task?
|
90
92
|
end
|
91
93
|
end
|
92
94
|
|
@@ -137,7 +139,7 @@ class PigeonProcessorTest < Minitest::Test
|
|
137
139
|
|
138
140
|
processor.queue = nil
|
139
141
|
|
140
|
-
|
142
|
+
assert_nil processor.queue
|
141
143
|
assert_equal [ ], queue.processors
|
142
144
|
end
|
143
145
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
|
3
3
|
class PigeonQueueTest < Minitest::Test
|
4
4
|
class TaggedTask < Pigeon::Task
|
@@ -20,7 +20,7 @@ class PigeonQueueTest < Minitest::Test
|
|
20
20
|
assert_equal 0, queue.length
|
21
21
|
assert_equal true, queue.empty?
|
22
22
|
|
23
|
-
|
23
|
+
assert_nil queue.pop
|
24
24
|
|
25
25
|
assert_equal [ ], queue.processors
|
26
26
|
end
|
@@ -80,6 +80,8 @@ class PigeonQueueTest < Minitest::Test
|
|
80
80
|
assert_equal 2, queue.length(:over_7)
|
81
81
|
|
82
82
|
pulled_task = queue.pop(:over_7)
|
83
|
+
|
84
|
+
assert pulled_task
|
83
85
|
|
84
86
|
assert_equal 9, queue.length
|
85
87
|
|
@@ -88,7 +90,7 @@ class PigeonQueueTest < Minitest::Test
|
|
88
90
|
|
89
91
|
queue.pop(:over_7)
|
90
92
|
|
91
|
-
|
93
|
+
assert_nil queue.peek(:over_7)
|
92
94
|
assert_equal 0, queue.length(:over_7)
|
93
95
|
assert_equal true, queue.empty?(:over_7)
|
94
96
|
|
@@ -104,7 +106,7 @@ class PigeonQueueTest < Minitest::Test
|
|
104
106
|
|
105
107
|
queue.claim(new_task)
|
106
108
|
|
107
|
-
|
109
|
+
assert_nil queue.peek(:over_7)
|
108
110
|
assert_equal 0, queue.length(:over_7)
|
109
111
|
assert_equal true, queue.empty?(:over_7)
|
110
112
|
end
|
@@ -146,7 +148,7 @@ class PigeonQueueTest < Minitest::Test
|
|
146
148
|
queue.include?(new_task)
|
147
149
|
end
|
148
150
|
|
149
|
-
|
151
|
+
assert_nil added_odd
|
150
152
|
|
151
153
|
odd_1 = queue << TaggedTask.new(11)
|
152
154
|
|
@@ -167,7 +169,7 @@ class PigeonQueueTest < Minitest::Test
|
|
167
169
|
# Observer callbacks are not triggered on existing data, only on new
|
168
170
|
# insertions.
|
169
171
|
assert_equal false, has_run
|
170
|
-
|
172
|
+
assert_nil claimed_task
|
171
173
|
assert_equal 7, queue.length
|
172
174
|
assert_equal 1, queue.length(:odd)
|
173
175
|
|
@@ -177,7 +179,7 @@ class PigeonQueueTest < Minitest::Test
|
|
177
179
|
queue.include?(new_task)
|
178
180
|
end
|
179
181
|
|
180
|
-
|
182
|
+
assert_nil claimed_task
|
181
183
|
assert_equal 8, queue.length
|
182
184
|
assert_equal 1, queue.length(:odd)
|
183
185
|
|
@@ -203,7 +205,7 @@ class PigeonQueueTest < Minitest::Test
|
|
203
205
|
queue.include?(new_task)
|
204
206
|
end
|
205
207
|
|
206
|
-
|
208
|
+
assert_nil claimed_task
|
207
209
|
assert_equal false, has_run
|
208
210
|
|
209
211
|
odd_2 = queue << TaggedTask.new(15)
|
@@ -232,7 +234,7 @@ class PigeonQueueTest < Minitest::Test
|
|
232
234
|
end
|
233
235
|
end
|
234
236
|
|
235
|
-
|
237
|
+
queue << TaggedTask.new(0)
|
236
238
|
|
237
239
|
assert_eventually(2) do
|
238
240
|
queue.peek
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require_relative '../helper'
|
2
2
|
|
3
3
|
class TerminateTask < Pigeon::Task
|
4
4
|
def state_initialized!
|
@@ -67,7 +67,7 @@ class PigeonTaskTest < Minitest::Test
|
|
67
67
|
assert_equal 1, reported
|
68
68
|
assert_equal :finished, task.state
|
69
69
|
|
70
|
-
|
70
|
+
assert_nil task.exception
|
71
71
|
|
72
72
|
assert_equal @engine.object_id, task.engine.object_id
|
73
73
|
end
|
@@ -99,7 +99,7 @@ class PigeonTaskTest < Minitest::Test
|
|
99
99
|
task.finished?
|
100
100
|
end
|
101
101
|
|
102
|
-
|
102
|
+
assert_nil task.exception
|
103
103
|
|
104
104
|
assert_equal :finished, task.state
|
105
105
|
|
data/test/unit/pigeon_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pigeon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Scott Tadman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -109,7 +109,7 @@ files:
|
|
109
109
|
- test/unit/pigeon_sorted_array_test.rb
|
110
110
|
- test/unit/pigeon_task_test.rb
|
111
111
|
- test/unit/pigeon_test.rb
|
112
|
-
homepage: http://github.com/
|
112
|
+
homepage: http://github.com/postageapp/pigeon
|
113
113
|
licenses: []
|
114
114
|
metadata: {}
|
115
115
|
post_install_message:
|
@@ -128,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
128
|
version: '0'
|
129
129
|
requirements: []
|
130
130
|
rubyforge_project:
|
131
|
-
rubygems_version: 2.
|
131
|
+
rubygems_version: 2.5.2
|
132
132
|
signing_key:
|
133
133
|
specification_version: 4
|
134
134
|
summary: Simple daemonized EventMachine engine framework with plug-in support
|