pigeon 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|