pigeon 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -48,7 +48,6 @@ An example would look like:
48
48
  engine = engine
49
49
 
50
50
  options = {
51
- :dir_mode => :normal,
52
51
  :dir => engine.pid_dir,
53
52
  :debug => true, # ((ENV['RAILS_ENV'] == 'production') ? ENV['PINGITY_DEBUG'] : true),
54
53
  :modules => [ ]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/bin/launcher.example CHANGED
@@ -4,7 +4,6 @@ COMMAND_NAME = 'launcher'
4
4
  engine = engine
5
5
 
6
6
  options = {
7
- :dir_mode => :normal,
8
7
  :dir => engine.pid_dir,
9
8
  :debug => true, # ((ENV['RAILS_ENV'] == 'production') ? ENV['PINGITY_DEBUG'] : true),
10
9
  :modules => [ ]
data/lib/pigeon/engine.rb CHANGED
@@ -45,7 +45,13 @@ class Pigeon::Engine
45
45
 
46
46
  def self.launch_with_options(options = nil)
47
47
  EventMachine.run do
48
- new(options_with_defaults(options)).run
48
+ engine = new(options_with_defaults(options))
49
+
50
+ Signal.trap('INT') do
51
+ engine.terminate
52
+ end
53
+
54
+ engine.run
49
55
  end
50
56
  end
51
57
 
@@ -63,29 +69,37 @@ class Pigeon::Engine
63
69
  end
64
70
 
65
71
  pid_file(options).create!(pid)
66
- yield(pid.to_i)
72
+
73
+ yield(pid) if (block_given?)
74
+
75
+ pid
67
76
  end
68
77
 
69
78
  def self.run(options = nil)
70
- yield($$)
79
+ yield($$) if (block_given?)
80
+
71
81
  launch_with_options((options || { }).merge(:foreground => true))
72
82
  end
73
83
 
74
84
  def self.stop(options = nil)
75
85
  pf = pid_file(options)
76
- pid = pf.contents
86
+ pid = pf.running
77
87
 
78
88
  if (pid)
79
89
  begin
80
- Process.kill('QUIT', pid)
90
+ Process.kill('INT', pid)
81
91
  rescue Errno::ESRCH
82
92
  # No such process exception
83
93
  pid = nil
84
94
  end
85
95
  pf.remove!
86
96
  end
97
+
98
+ pid = pid.to_i if (pid)
87
99
 
88
- yield(pid)
100
+ yield(pid) if (block_given?)
101
+
102
+ pid
89
103
  end
90
104
 
91
105
  def self.restart(options = nil)
@@ -94,7 +108,11 @@ class Pigeon::Engine
94
108
  end
95
109
 
96
110
  def self.status(options = nil)
97
- yield(pid_file(options).contents)
111
+ pid = pid_file(options).running
112
+
113
+ yield(pid) if (block_given?)
114
+
115
+ pid
98
116
  end
99
117
 
100
118
  def self.sql_logger
@@ -192,7 +210,9 @@ class Pigeon::Engine
192
210
 
193
211
  # Shuts down the engine.
194
212
  def terminate
213
+ run_chain(:before_stop)
195
214
  EventMachine.stop_event_loop
215
+ run_chain(:after_stop)
196
216
  end
197
217
 
198
218
  # Used to queue a block for immediate processing on a background thread.
@@ -1,5 +1,9 @@
1
1
  class Pigeon::Pidfile
2
2
  # == Constants ============================================================
3
+
4
+ # == Properties ===========================================================
5
+
6
+ attr_reader :path
3
7
 
4
8
  # == Class Methods ========================================================
5
9
 
@@ -11,7 +15,19 @@ class Pigeon::Pidfile
11
15
  @path += '.pid' unless (@path.match(/\./))
12
16
  end
13
17
 
14
- def contents
18
+ def running?
19
+ !!self.running
20
+ end
21
+
22
+ def running
23
+ pid = self.saved_pid
24
+
25
+ (pid and Process.kill(0, pid)) ? pid : nil
26
+ rescue Errno::ESRCH
27
+ nil
28
+ end
29
+
30
+ def saved_pid
15
31
  File.read(@path).to_i
16
32
  rescue Errno::ENOENT
17
33
  nil
@@ -19,17 +35,17 @@ class Pigeon::Pidfile
19
35
 
20
36
  def create!(pid = nil)
21
37
  open(@path, 'w') do |fh|
22
- fh.puts pid || $$
38
+ fh.puts(pid || $$)
23
39
  end
24
40
  end
25
41
 
26
42
  def remove!
27
- return unless (exists?)
43
+ return unless (exist?)
28
44
 
29
45
  File.unlink(@path)
30
46
  end
31
47
 
32
- def exists?
48
+ def exist?
33
49
  File.exist?(@path)
34
50
  end
35
51
  end
data/pigeon.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{pigeon}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.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 = %q{2010-10-01}
12
+ s.date = %q{2010-10-05}
13
13
  s.default_executable = %q{launcher.example}
14
14
  s.description = %q{Pigeon is a simple way to get started building an EventMachine engine that's intended to run as a background job.}
15
15
  s.email = %q{github@tadman.ca}
@@ -20,8 +20,44 @@ class TestEngine < Pigeon::Engine
20
20
  end
21
21
  end
22
22
 
23
+ class ShutdownEngine < Pigeon::Engine
24
+ after_start do
25
+ self.terminate
26
+ end
27
+ end
28
+
29
+ class CallbackTestEngine < Pigeon::Engine
30
+ after_initialize do
31
+ self.track(:after_initialize)
32
+ end
33
+
34
+ before_start do
35
+ self.track(:before_start)
36
+ end
37
+
38
+ after_start do
39
+ self.track(:after_start)
40
+ end
41
+
42
+ before_stop do
43
+ self.track(:before_stop)
44
+ end
45
+
46
+ after_stop do
47
+ self.track(:after_stop)
48
+ @options[:pipe].close
49
+ end
50
+
51
+ def track(callback)
52
+ pipe = @options[:pipe]
53
+
54
+ pipe.puts(callback.to_s)
55
+ pipe.flush
56
+ end
57
+ end
58
+
23
59
  class TestPigeonEngine < Test::Unit::TestCase
24
- def test_create_subclass
60
+ def test_example_subclass
25
61
  engine_pid = nil
26
62
 
27
63
  read_fd, write_fd = IO.pipe
@@ -31,6 +67,8 @@ class TestPigeonEngine < Test::Unit::TestCase
31
67
  engine_pid = pid
32
68
  end
33
69
 
70
+ write_fd.close
71
+
34
72
  Timeout::timeout(5) do
35
73
  assert_equal "STARTED\n", read_fd.readline
36
74
  end
@@ -47,4 +85,83 @@ class TestPigeonEngine < Test::Unit::TestCase
47
85
  assert_equal nil, pid
48
86
  end
49
87
  end
88
+
89
+ def test_example_subclass_without_blocks
90
+ engine_pid = nil
91
+
92
+ read_fd, write_fd = IO.pipe
93
+
94
+ engine_pid = TestEngine.start(:pipe => write_fd)
95
+
96
+ write_fd.close
97
+
98
+ assert engine_pid
99
+
100
+ Timeout::timeout(5) do
101
+ assert_equal "STARTED\n", read_fd.readline
102
+ end
103
+
104
+ running_pid = TestEngine.status
105
+
106
+ assert_equal engine_pid, running_pid
107
+
108
+ assert_equal engine_pid, TestEngine.stop
109
+
110
+ assert_equal nil, TestEngine.status
111
+ end
112
+
113
+ def test_callbacks
114
+ engine_pid = nil
115
+
116
+ read_fd, write_fd = IO.pipe
117
+
118
+ CallbackTestEngine.start(:pipe => write_fd) do |pid|
119
+ assert pid
120
+ engine_pid = pid
121
+ end
122
+
123
+ write_fd.close
124
+
125
+ CallbackTestEngine.status do |pid|
126
+ assert_equal engine_pid, pid
127
+ end
128
+
129
+ CallbackTestEngine.stop do |pid|
130
+ assert_equal engine_pid, pid
131
+ end
132
+
133
+ CallbackTestEngine.status do |pid|
134
+ assert_equal nil, pid
135
+ end
136
+
137
+ expected_callbacks = [
138
+ :after_initialize,
139
+ :before_start,
140
+ :after_start,
141
+ :before_stop,
142
+ :after_stop
143
+ ].freeze
144
+
145
+ assert_equal expected_callbacks, read_fd.read.split(/\n/).collect(&:to_sym)
146
+ end
147
+
148
+ def test_shutdown_engine
149
+ engine_pid = nil
150
+
151
+ ShutdownEngine.start do |pid|
152
+ engine_pid = pid
153
+ end
154
+
155
+ assert engine_pid
156
+
157
+ sleep(1)
158
+
159
+ running_pid = nil
160
+
161
+ ShutdownEngine.status do |pid|
162
+ running_pid = pid
163
+ end
164
+
165
+ assert_equal nil, running_pid
166
+ end
50
167
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - tadman
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-01 00:00:00 -04:00
17
+ date: 2010-10-05 00:00:00 -04:00
18
18
  default_executable: launcher.example
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency