havanna 1.0.0 → 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/CHANGELOG.md +8 -0
- data/README.md +42 -20
- data/bin/havanna +8 -5
- data/lib/havanna.rb +5 -7
- data/lib/havanna/worker.rb +7 -0
- data/test/havanna_test.rb +17 -15
- data/test/workers/echo/Havannafile +4 -2
- data/test/workers/logger/logger.rb +3 -1
- data/test/workers/slow/slow.rb +3 -1
- metadata +4 -3
- data/test/workers/echo/echo.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4067d3aa7fa9709542485efc5a24afbe69d6a0d8
|
4
|
+
data.tar.gz: 7a5919caa52c44b111082c6a2dbab0d81fdc7777
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d00fb0b93047de33f2d27f8ef239125bb1db26e12db91358c2f36e6e9d2f6d5857d86d661b2e2d3db9ec7c2387d22ad4e96ddba8d7afbc87c6fe9b687808780
|
7
|
+
data.tar.gz: 65c38b4356e5876c6340d3a963ab83267d03fe66191b4c108f1b94b9ebbd8ccbccbb9ad485fe86871d847f85c76a71001bd279d94e56c4df20d21685c22c2155
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
1.1.0 - 2015-08-05
|
2
|
+
==================
|
3
|
+
|
4
|
+
* Havanna now exits forcefully when receiving INT or TERM twice within 5
|
5
|
+
seconds.
|
6
|
+
|
7
|
+
* Workers listed in `Havannafile` must respond to `#to_h`. If you were using
|
8
|
+
your own classes, make them inherit from `Havanna::Worker`.
|
data/README.md
CHANGED
@@ -3,25 +3,57 @@ Havanna
|
|
3
3
|
|
4
4
|
Ruby workers with [Disque][disque].
|
5
5
|
|
6
|
+
|
6
7
|
Usage
|
7
8
|
-----
|
8
9
|
|
9
|
-
|
10
|
+
Similar to Rack's `config.ru`, Havanna has an entry point file where you
|
11
|
+
explicitly declare handlers for your queues.
|
12
|
+
The minimum you need to use Havanna is to create a `Havannafile`:
|
13
|
+
|
14
|
+
```
|
15
|
+
require "app"
|
16
|
+
|
17
|
+
Havanna.run(Hello: -> job {
|
18
|
+
puts("Hello, #{job}")
|
19
|
+
})
|
20
|
+
```
|
21
|
+
|
22
|
+
Now on the command line, start Havanna:
|
23
|
+
|
24
|
+
```
|
25
|
+
$ havanna start
|
26
|
+
```
|
27
|
+
|
28
|
+
In a different window, try queuing a job using Disque's built-in client:
|
29
|
+
|
30
|
+
```
|
31
|
+
$ disque addjob Hello world 5000
|
32
|
+
```
|
33
|
+
|
34
|
+
As expected, you should see the string "Hello, world" in the terminal where you
|
35
|
+
started Havanna.
|
36
|
+
|
37
|
+
|
38
|
+
Workers
|
39
|
+
-------
|
40
|
+
|
41
|
+
If you prefer to use classes to model your workers, there's `Havanna::Worker`.
|
42
|
+
For instance, this could be `workers/mailer.rb`:
|
10
43
|
|
11
44
|
```ruby
|
12
|
-
|
45
|
+
require "havanna/worker"
|
46
|
+
|
47
|
+
class Mailer < Havanna::Worker
|
13
48
|
def call(item)
|
14
|
-
puts
|
49
|
+
puts("Emailing #{item}...")
|
15
50
|
|
16
51
|
# Actually do it.
|
17
52
|
end
|
18
53
|
end
|
19
54
|
```
|
20
55
|
|
21
|
-
|
22
|
-
your workers. Similar to Rack's `config.ru`, Havanna has an
|
23
|
-
entry point file where you explicitly declare your workers.
|
24
|
-
This would be a valid `Havannafile`:
|
56
|
+
Then your `Havannafile` would look like this:
|
25
57
|
|
26
58
|
```ruby
|
27
59
|
require "app"
|
@@ -29,21 +61,11 @@ require "app"
|
|
29
61
|
Havanna.run(Mailer)
|
30
62
|
```
|
31
63
|
|
32
|
-
Now on the command line, start your workers:
|
33
|
-
|
34
|
-
```
|
35
|
-
$ havanna start
|
36
|
-
```
|
37
|
-
|
38
|
-
In a different window, try queuing a job using Disque's
|
39
|
-
built-in client:
|
40
64
|
|
41
|
-
|
42
|
-
|
43
|
-
```
|
65
|
+
Administration
|
66
|
+
--------------
|
44
67
|
|
45
|
-
Once you're up and running, deploy your workers with `-d`
|
46
|
-
for daemonization:
|
68
|
+
Once you're up and running, deploy your workers with `-d` for daemonization:
|
47
69
|
|
48
70
|
```
|
49
71
|
$ havanna start -d
|
data/bin/havanna
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
|
3
|
+
stop_requested_at = nil
|
4
|
+
|
3
5
|
stop = proc do
|
4
|
-
if
|
6
|
+
if stop_requested_at && Time.now - stop_requested_at < 5
|
7
|
+
exit 0
|
8
|
+
elsif defined?(Havanna)
|
5
9
|
Havanna.stop
|
10
|
+
stop_requested_at = Time.now
|
6
11
|
else
|
7
12
|
exit 0
|
8
13
|
end
|
@@ -14,7 +19,7 @@ trap(:TERM, &stop)
|
|
14
19
|
usage = <<-EOS
|
15
20
|
Usage:
|
16
21
|
|
17
|
-
havanna start [-r <require>] [-d] [-p <pid-path>] [-l <log-path>]
|
22
|
+
havanna start [-r <require>] [-d] [-p <pid-path>] [-l <log-path>] [-s <pool-size>
|
18
23
|
havanna stop [-p <pid-path>]
|
19
24
|
|
20
25
|
EOS
|
@@ -44,8 +49,6 @@ command, _ = Clap.run ARGV,
|
|
44
49
|
opts[:requires] << file
|
45
50
|
},
|
46
51
|
"-v" => -> {
|
47
|
-
require_relative "../lib/havanna/version"
|
48
|
-
|
49
52
|
puts Havanna::VERSION
|
50
53
|
|
51
54
|
exit 0
|
@@ -104,7 +107,7 @@ when "start"
|
|
104
107
|
accum.concat(Array.new(threads_per_worker) do
|
105
108
|
Thread.new(worker) do |worker|
|
106
109
|
Thread.current.abort_on_exception = true
|
107
|
-
Havanna.start(worker)
|
110
|
+
Havanna.start(*worker.to_h.to_a.first)
|
108
111
|
end
|
109
112
|
end)
|
110
113
|
end
|
data/lib/havanna.rb
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
require "disque"
|
2
2
|
|
3
3
|
module Havanna
|
4
|
-
VERSION = "1.
|
4
|
+
VERSION = "1.1.0"
|
5
5
|
|
6
6
|
def self.connect(*args)
|
7
7
|
@connect = args
|
8
8
|
@disque = Disque.new(*args)
|
9
9
|
end
|
10
10
|
|
11
|
-
def self.start(
|
12
|
-
instance = worker.new
|
13
|
-
|
11
|
+
def self.start(name, handler)
|
14
12
|
begin
|
15
13
|
disque = Disque.new(*@connect)
|
16
14
|
|
17
|
-
printf("Started worker %s\n",
|
15
|
+
printf("Started worker %s\n", name)
|
18
16
|
|
19
17
|
loop do
|
20
|
-
disque.fetch(from: [
|
21
|
-
|
18
|
+
disque.fetch(from: [name], timeout: 5000) do |job|
|
19
|
+
handler.call(job)
|
22
20
|
end
|
23
21
|
|
24
22
|
break if @stop
|
data/test/havanna_test.rb
CHANGED
@@ -11,7 +11,7 @@ def wait_for_pid(pid)
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def wait_for_child(pid)
|
14
|
-
Timeout.timeout(
|
14
|
+
Timeout.timeout(6) do
|
15
15
|
Process.wait(pid)
|
16
16
|
end
|
17
17
|
end
|
@@ -45,6 +45,8 @@ def root(path)
|
|
45
45
|
File.expand_path("../#{path}", File.dirname(__FILE__))
|
46
46
|
end
|
47
47
|
|
48
|
+
LIB = root("lib")
|
49
|
+
|
48
50
|
disque = Disque.new("127.0.0.1:7711")
|
49
51
|
|
50
52
|
prepare do
|
@@ -56,7 +58,7 @@ test "start" do
|
|
56
58
|
pid = nil
|
57
59
|
|
58
60
|
begin
|
59
|
-
pid = spawn("#{root("bin/havanna")} start", chdir: "test/workers/echo")
|
61
|
+
pid = spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} start", chdir: "test/workers/echo")
|
60
62
|
|
61
63
|
disque.push("Echo", 2, 5000)
|
62
64
|
|
@@ -72,7 +74,7 @@ test "gracefully handles TERM signals" do
|
|
72
74
|
disque.push("Slow", 3, 5000)
|
73
75
|
|
74
76
|
begin
|
75
|
-
spawn("#{root("bin/havanna")} -d start", chdir: "test/workers/slow")
|
77
|
+
spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} -d start", chdir: "test/workers/slow")
|
76
78
|
|
77
79
|
pid = read_pid_file("./test/workers/slow/havanna.pid")
|
78
80
|
|
@@ -87,11 +89,11 @@ test "gracefully handles TERM signals" do
|
|
87
89
|
end
|
88
90
|
|
89
91
|
test "stop waits for workers to be done" do
|
90
|
-
spawn("#{root("bin/havanna")} start -d", chdir: "test/workers/slow")
|
92
|
+
spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} start -d", chdir: "test/workers/slow")
|
91
93
|
|
92
94
|
pid = read_pid_file("./test/workers/slow/havanna.pid")
|
93
95
|
|
94
|
-
stopper = spawn("#{root("bin/havanna")} stop", chdir: "test/workers/slow")
|
96
|
+
stopper = spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} stop", chdir: "test/workers/slow")
|
95
97
|
|
96
98
|
# Let the stop command start.
|
97
99
|
wait_for { running?(stopper) }
|
@@ -112,7 +114,7 @@ test "use a specific path for the pid file" do
|
|
112
114
|
pid_path = "./test/workers/echo/foo.pid"
|
113
115
|
|
114
116
|
begin
|
115
|
-
spawn("#{root("bin/havanna")} -d start -p foo.pid", chdir: "test/workers/echo")
|
117
|
+
spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} -d start -p foo.pid", chdir: "test/workers/echo")
|
116
118
|
|
117
119
|
pid = read_pid_file(pid_path)
|
118
120
|
|
@@ -130,13 +132,13 @@ test "load Havannafile" do
|
|
130
132
|
pid = nil
|
131
133
|
|
132
134
|
begin
|
133
|
-
pid = spawn("#{root("bin/havanna")} start", chdir: "test/workers/echo")
|
135
|
+
pid = spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} start", chdir: "test/workers/echo")
|
134
136
|
|
135
137
|
disque.push("Echo", 2, 5000)
|
136
138
|
|
137
139
|
value = wait_for { disque.fetch(from: ["Echo:result"]) }
|
138
140
|
|
139
|
-
assert_equal "2", value
|
141
|
+
assert_equal "2", value[0][2]
|
140
142
|
ensure
|
141
143
|
Process.kill(:INT, pid) if pid
|
142
144
|
end
|
@@ -152,13 +154,13 @@ test "redirect stdout and stderr to a log file when daemonizing" do
|
|
152
154
|
File.delete(log_path) if File.exist?(log_path)
|
153
155
|
|
154
156
|
begin
|
155
|
-
pid = spawn("#{root("bin/havanna")} -d start", chdir: "test/workers/logger")
|
157
|
+
pid = spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} -d start", chdir: "test/workers/logger")
|
156
158
|
|
157
159
|
assert wait_for {
|
158
160
|
`ps -p #{pid} -o state`.lines.to_a.last[/(\w+)/, 1] == "Z"
|
159
161
|
}
|
160
162
|
|
161
|
-
|
163
|
+
disque.push("Logger", "1", 5000)
|
162
164
|
ensure
|
163
165
|
detached_pid = read_pid_file(pid_path)
|
164
166
|
|
@@ -168,7 +170,7 @@ test "redirect stdout and stderr to a log file when daemonizing" do
|
|
168
170
|
|
169
171
|
wait_for_pid(detached_pid)
|
170
172
|
|
171
|
-
assert_equal "
|
173
|
+
assert_equal "Started worker Logger\nout: 1\nerr: 1\n", File.read(log_path)
|
172
174
|
end
|
173
175
|
|
174
176
|
test "redirect stdout and stderr to a different log file when daemonizing" do
|
@@ -181,13 +183,13 @@ test "redirect stdout and stderr to a different log file when daemonizing" do
|
|
181
183
|
File.delete(log_path) if File.exist?(log_path)
|
182
184
|
|
183
185
|
begin
|
184
|
-
pid = spawn("#{root("bin/havanna")} -d -l foo.log start", chdir: "test/workers/logger")
|
186
|
+
pid = spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} -d -l foo.log start", chdir: "test/workers/logger")
|
185
187
|
|
186
188
|
assert wait_for {
|
187
189
|
`ps -p #{pid} -o state`.lines.to_a.last[/(\w+)/, 1] == "Z"
|
188
190
|
}
|
189
191
|
|
190
|
-
|
192
|
+
disque.push("Logger", "1", 5000)
|
191
193
|
ensure
|
192
194
|
detached_pid = read_pid_file(pid_path)
|
193
195
|
|
@@ -197,7 +199,7 @@ test "redirect stdout and stderr to a different log file when daemonizing" do
|
|
197
199
|
|
198
200
|
wait_for_pid(detached_pid)
|
199
201
|
|
200
|
-
assert_equal "
|
202
|
+
assert_equal "Started worker Logger\nout: 1\nerr: 1\n", File.read(log_path)
|
201
203
|
end
|
202
204
|
|
203
205
|
test "daemonizes" do
|
@@ -206,7 +208,7 @@ test "daemonizes" do
|
|
206
208
|
pid_path = "./test/workers/echo/havanna.pid"
|
207
209
|
|
208
210
|
begin
|
209
|
-
pid = spawn("#{root("bin/havanna")} -d start", chdir: "test/workers/echo")
|
211
|
+
pid = spawn({"RUBYLIB" => LIB}, "#{root("bin/havanna")} -d start", chdir: "test/workers/echo")
|
210
212
|
|
211
213
|
assert wait_for {
|
212
214
|
`ps -p #{pid} -o state`.lines.to_a.last[/(\w+)/, 1] == "Z"
|
data/test/workers/slow/slow.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: havanna
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damian Janowski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: disque
|
@@ -61,15 +61,16 @@ extensions: []
|
|
61
61
|
extra_rdoc_files: []
|
62
62
|
files:
|
63
63
|
- .gitignore
|
64
|
+
- CHANGELOG.md
|
64
65
|
- LICENSE
|
65
66
|
- README.md
|
66
67
|
- bin/havanna
|
67
68
|
- havanna.gemspec
|
68
69
|
- lib/havanna.rb
|
70
|
+
- lib/havanna/worker.rb
|
69
71
|
- makefile
|
70
72
|
- test/havanna_test.rb
|
71
73
|
- test/workers/echo/Havannafile
|
72
|
-
- test/workers/echo/echo.rb
|
73
74
|
- test/workers/logger/Havannafile
|
74
75
|
- test/workers/logger/logger.rb
|
75
76
|
- test/workers/slow/Havannafile
|