xing-gearman-ruby 1.0.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/.gitignore +1 -0
- data/LICENSE +20 -0
- data/README +9 -0
- data/Rakefile +40 -0
- data/VERSION.yml +4 -0
- data/examples/Net/Gearman/Client.php +290 -0
- data/examples/Net/Gearman/Connection.php +410 -0
- data/examples/Net/Gearman/Exception.php +42 -0
- data/examples/Net/Gearman/Job/Common.php +135 -0
- data/examples/Net/Gearman/Job/Exception.php +45 -0
- data/examples/Net/Gearman/Job/Sleep.php +33 -0
- data/examples/Net/Gearman/Job.php +85 -0
- data/examples/Net/Gearman/Manager.php +320 -0
- data/examples/Net/Gearman/Set.php +215 -0
- data/examples/Net/Gearman/Task.php +300 -0
- data/examples/Net/Gearman/Worker.php +455 -0
- data/examples/client.php +23 -0
- data/examples/client.rb +15 -0
- data/examples/scale_image.rb +32 -0
- data/examples/scale_image_worker.rb +34 -0
- data/examples/server.rb +13 -0
- data/examples/worker.php +15 -0
- data/examples/worker.rb +23 -0
- data/gearman-ruby.gemspec +81 -0
- data/lib/gearman/client.rb +139 -0
- data/lib/gearman/server.rb +94 -0
- data/lib/gearman/task.rb +128 -0
- data/lib/gearman/taskset.rb +241 -0
- data/lib/gearman/testlib.rb +96 -0
- data/lib/gearman/util.rb +212 -0
- data/lib/gearman/worker.rb +341 -0
- data/lib/gearman.rb +76 -0
- data/test/client_test.rb +111 -0
- data/test/mock_client_test.rb +431 -0
- data/test/mock_worker_test.rb +213 -0
- data/test/worker_test.rb +61 -0
- metadata +98 -0
@@ -0,0 +1,213 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift('../lib')
|
4
|
+
require 'gearman'
|
5
|
+
require 'gearman/testlib'
|
6
|
+
require 'test/unit'
|
7
|
+
require 'thread'
|
8
|
+
|
9
|
+
Thread.abort_on_exception = true
|
10
|
+
|
11
|
+
class TestWorker < Test::Unit::TestCase
|
12
|
+
def setup
|
13
|
+
@server = FakeJobServer.new(self)
|
14
|
+
@server2 = FakeJobServer.new(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
@server.stop
|
19
|
+
@server2.stop
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_complete
|
23
|
+
@server = FakeJobServer.new(self)
|
24
|
+
worker = nil
|
25
|
+
sock = nil
|
26
|
+
|
27
|
+
s = TestScript.new
|
28
|
+
w = TestScript.new
|
29
|
+
|
30
|
+
server_thread = Thread.new { s.loop_forever }.run
|
31
|
+
worker_thread = Thread.new { w.loop_forever }.run
|
32
|
+
|
33
|
+
# Create a worker and wait for it to connect to us.
|
34
|
+
w.exec {
|
35
|
+
worker = Gearman::Worker.new(
|
36
|
+
"localhost:#{@server.port}", { :client_id => 'test' })
|
37
|
+
}
|
38
|
+
s.exec { sock = @server.expect_connection }
|
39
|
+
s.wait
|
40
|
+
|
41
|
+
# After it connects, it should send its ID, and it should tell us its
|
42
|
+
# abilities when we report them.
|
43
|
+
s.exec { @server.expect_request(sock, :set_client_id, 'test') }
|
44
|
+
w.exec { worker.add_ability('echo') {|d,j| j.report_status(1, 1); d } }
|
45
|
+
s.exec { @server.expect_request(sock, :can_do, 'echo') }
|
46
|
+
|
47
|
+
# It should try to grab a job when we tell it to work.
|
48
|
+
w.exec { worker.work }
|
49
|
+
s.exec { @server.expect_request(sock, :grab_job) }
|
50
|
+
|
51
|
+
# If we tell it there aren't any jobs, it should go to sleep.
|
52
|
+
s.exec { @server.send_response(sock, :no_job) }
|
53
|
+
s.exec { @server.expect_request(sock, :pre_sleep) }
|
54
|
+
|
55
|
+
# When we send it a noop, it should wake up and ask for a job again.
|
56
|
+
s.exec { @server.send_response(sock, :noop) }
|
57
|
+
s.exec { @server.expect_request(sock, :grab_job) }
|
58
|
+
|
59
|
+
# When we give it a job, it should do it.
|
60
|
+
s.exec { @server.send_response(sock, :job_assign, "a\0echo\0foo") }
|
61
|
+
s.exec { @server.expect_request(sock, :work_status, "a\0001\0001") }
|
62
|
+
s.exec { @server.expect_request(sock, :work_complete, "a\0foo") }
|
63
|
+
|
64
|
+
# Test that functions are unregistered correctly.
|
65
|
+
w.exec { worker.remove_ability('echo') }
|
66
|
+
s.exec { @server.expect_request(sock, :cant_do, 'echo') }
|
67
|
+
s.wait
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_multiple_servers
|
71
|
+
# This is cheesy. We want to know the order that Worker#work will
|
72
|
+
# iterate through the servers, so we make sure that server1 will be the
|
73
|
+
# first one when the names are lexographically sorted.
|
74
|
+
if @server2.port.to_s < @server.port.to_s
|
75
|
+
tmp = @server
|
76
|
+
@server = @server2
|
77
|
+
@server2 = tmp
|
78
|
+
end
|
79
|
+
worker = nil
|
80
|
+
sock1, sock2 = nil
|
81
|
+
|
82
|
+
s1 = TestScript.new
|
83
|
+
s2 = TestScript.new
|
84
|
+
w = TestScript.new
|
85
|
+
|
86
|
+
@server_thread = Thread.new { s1.loop_forever }.run
|
87
|
+
@server2_thread = Thread.new { s2.loop_forever }.run
|
88
|
+
worker_thread = Thread.new { w.loop_forever }.run
|
89
|
+
|
90
|
+
# Create a worker, which should connect to both servers.
|
91
|
+
w.exec {
|
92
|
+
worker = Gearman::Worker.new(
|
93
|
+
nil, { :client_id => 'test', :reconnect_sec => 0.1 }) }
|
94
|
+
w.exec { worker.add_ability('foo') {|d,j| 'bar' } }
|
95
|
+
w.exec {
|
96
|
+
worker.job_servers =
|
97
|
+
[ "localhost:#{@server.port}", "localhost:#{@server2.port}" ]
|
98
|
+
}
|
99
|
+
s1.exec { sock1 = @server.expect_connection }
|
100
|
+
s2.exec { sock2 = @server2.expect_connection }
|
101
|
+
s1.wait
|
102
|
+
s2.wait
|
103
|
+
|
104
|
+
# It should register itself with both.
|
105
|
+
s1.exec { @server.expect_request(sock1, :set_client_id, 'test') }
|
106
|
+
s1.exec { @server.expect_request(sock1, :can_do, 'foo') }
|
107
|
+
s2.exec { @server2.expect_request(sock2, :set_client_id, 'test') }
|
108
|
+
s2.exec { @server2.expect_request(sock2, :can_do, 'foo') }
|
109
|
+
|
110
|
+
# It should try to get a job from both servers and then sleep.
|
111
|
+
w.exec { worker.work }
|
112
|
+
s1.exec { @server.expect_request(sock1, :grab_job) }
|
113
|
+
s1.exec { @server.send_response(sock1, :no_job) }
|
114
|
+
s2.exec { @server2.expect_request(sock2, :grab_job) }
|
115
|
+
s2.exec { @server2.send_response(sock2, :no_job) }
|
116
|
+
s1.exec { @server.expect_request(sock1, :pre_sleep) }
|
117
|
+
s2.exec { @server2.expect_request(sock2, :pre_sleep) }
|
118
|
+
|
119
|
+
# If the second server wakes it up, it should again try to get a job
|
120
|
+
# and then do it.
|
121
|
+
s2.exec { @server2.send_response(sock2, :noop) }
|
122
|
+
s1.exec { @server.expect_request(sock1, :grab_job) }
|
123
|
+
s1.exec { @server.send_response(sock1, :no_job) }
|
124
|
+
s2.exec { @server2.expect_request(sock2, :grab_job) }
|
125
|
+
s2.exec { @server2.send_response(sock2, :job_assign, "a\0foo\0") }
|
126
|
+
s2.exec { @server2.expect_request(sock2, :work_complete, "a\0bar") }
|
127
|
+
|
128
|
+
w.wait
|
129
|
+
s1.wait
|
130
|
+
s2.wait
|
131
|
+
|
132
|
+
# Stop the first job server and make the worker try to reconnect to
|
133
|
+
# both.
|
134
|
+
old_servers = worker.job_servers
|
135
|
+
@server.stop
|
136
|
+
worker.job_servers = []
|
137
|
+
worker.job_servers = old_servers
|
138
|
+
s2.exec { sock2 = @server2.expect_connection }
|
139
|
+
s2.wait
|
140
|
+
|
141
|
+
# It shouldn't have any trouble with the second server. Tell it to go
|
142
|
+
# to work.
|
143
|
+
s2.exec { @server2.expect_request(sock2, :set_client_id, 'test') }
|
144
|
+
s2.exec { @server2.expect_request(sock2, :can_do, 'foo') }
|
145
|
+
w.exec { worker.work }
|
146
|
+
s2.exec { @server2.expect_request(sock2, :grab_job) }
|
147
|
+
s2.exec { @server2.send_response(sock2, :no_job) }
|
148
|
+
s2.exec { @server2.expect_request(sock2, :pre_sleep) }
|
149
|
+
s2.wait
|
150
|
+
|
151
|
+
# Start the first server and wait for the worker to connect to it and
|
152
|
+
# register.
|
153
|
+
@server.start
|
154
|
+
s1.exec { sock1 = @server.expect_connection }
|
155
|
+
s1.wait
|
156
|
+
s1.exec { @server.expect_request(sock1, :set_client_id, 'test') }
|
157
|
+
s1.exec { @server.expect_request(sock1, :can_do, 'foo') }
|
158
|
+
s1.wait
|
159
|
+
|
160
|
+
# Let the second server wake the worker up and then give it a job.
|
161
|
+
s2.exec { @server2.send_response(sock2, :noop) }
|
162
|
+
s1.exec { @server.expect_request(sock1, :grab_job) }
|
163
|
+
s1.exec { @server.send_response(sock1, :no_job) }
|
164
|
+
s2.exec { @server2.expect_request(sock2, :grab_job) }
|
165
|
+
s2.exec { @server2.send_response(sock2, :job_assign, "a\0foo\0") }
|
166
|
+
s2.exec { @server2.expect_request(sock2, :work_complete, "a\0bar") }
|
167
|
+
s1.wait
|
168
|
+
s2.wait
|
169
|
+
w.wait
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_timeout
|
173
|
+
worker = nil
|
174
|
+
sock = nil
|
175
|
+
|
176
|
+
s = TestScript.new
|
177
|
+
w = TestScript.new
|
178
|
+
|
179
|
+
server_thread = Thread.new { s.loop_forever }.run
|
180
|
+
worker_thread = Thread.new { w.loop_forever }.run
|
181
|
+
|
182
|
+
w.exec {
|
183
|
+
worker = Gearman::Worker.new("localhost:#{@server.port}",
|
184
|
+
{ :client_id => 'test',
|
185
|
+
:reconnect_sec => 0.15,
|
186
|
+
:network_timeout_sec => 0.1 })
|
187
|
+
}
|
188
|
+
s.exec { sock = @server.expect_connection }
|
189
|
+
s.wait
|
190
|
+
s.exec { @server.expect_request(sock, :set_client_id, 'test') }
|
191
|
+
|
192
|
+
w.exec { worker.add_ability('foo') {|d,j| 'bar' } }
|
193
|
+
s.exec { @server.expect_request(sock, :can_do, 'foo') }
|
194
|
+
|
195
|
+
# Don't do anything after the client asks for a job.
|
196
|
+
w.exec { worker.work }
|
197
|
+
s.exec { @server.expect_request(sock, :grab_job) }
|
198
|
+
s.exec { sleep 0.16 }
|
199
|
+
s.wait
|
200
|
+
|
201
|
+
# The client should reconnect and ask for a job again.
|
202
|
+
s.exec { sock = @server.expect_connection }
|
203
|
+
s.wait
|
204
|
+
|
205
|
+
s.exec { @server.expect_request(sock, :set_client_id, 'test') }
|
206
|
+
s.exec { @server.expect_request(sock, :can_do, 'foo') }
|
207
|
+
s.exec { @server.expect_request(sock, :grab_job) }
|
208
|
+
s.exec { @server.send_response(sock, :job_assign, "a\0foo\0") }
|
209
|
+
s.exec { @server.expect_request(sock, :work_complete, "a\0bar") }
|
210
|
+
s.wait
|
211
|
+
w.wait
|
212
|
+
end
|
213
|
+
end
|
data/test/worker_test.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'mocha'
|
4
|
+
|
5
|
+
$:.unshift('../lib')
|
6
|
+
require 'gearman'
|
7
|
+
require 'gearman/testlib'
|
8
|
+
require 'test/unit'
|
9
|
+
|
10
|
+
class TestClient < Test::Unit::TestCase
|
11
|
+
##
|
12
|
+
# Test Gearman::Worker::Ability.
|
13
|
+
def test_ability
|
14
|
+
data, job = nil
|
15
|
+
ability = Gearman::Worker::Ability.new(
|
16
|
+
Proc.new {|d, j| data = d; job = j; true }, 5)
|
17
|
+
assert_equal(5, ability.timeout)
|
18
|
+
assert_equal(true, ability.run(1, 2))
|
19
|
+
assert_equal(1, data)
|
20
|
+
assert_equal(2, job)
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Test Gearman::Worker::Job.
|
25
|
+
def test_job
|
26
|
+
server = FakeJobServer.new(self)
|
27
|
+
Thread.new do
|
28
|
+
sock = TCPSocket.new('localhost', server.port)
|
29
|
+
job = Gearman::Worker::Job.new(sock, 'handle')
|
30
|
+
job.report_status(10, 20)
|
31
|
+
end.run
|
32
|
+
sock = server.expect_connection
|
33
|
+
server.expect_request(sock, :work_status, "handle\00010\00020")
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_job_reconnection
|
38
|
+
server = FakeJobServer.new(self)
|
39
|
+
Thread.new do
|
40
|
+
sock = server.expect_connection
|
41
|
+
server.expect_anything_and_close_socket(sock)
|
42
|
+
end
|
43
|
+
|
44
|
+
servers = ["localhost:#{server.port}"]
|
45
|
+
w = Gearman::Worker.new(servers)
|
46
|
+
Gearman::Util.stubs(:send_request).raises(Exception.new)
|
47
|
+
w.add_ability('sleep') do |data,job|
|
48
|
+
seconds = data
|
49
|
+
(1..seconds.to_i).each do |i|
|
50
|
+
sleep 1
|
51
|
+
print i
|
52
|
+
# Report our progress to the job server every second.
|
53
|
+
job.report_status(i, seconds)
|
54
|
+
end
|
55
|
+
# Report success.
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
assert(w.bad_servers.size == 1)
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xing-gearman-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Erat
|
8
|
+
- Ladislav Martincik
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-06-25 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: Library for the Gearman distributed job system
|
18
|
+
email: ladislav.martincik@xing.com
|
19
|
+
executables: []
|
20
|
+
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- LICENSE
|
25
|
+
- README
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README
|
30
|
+
- Rakefile
|
31
|
+
- VERSION.yml
|
32
|
+
- examples/Net/Gearman/Client.php
|
33
|
+
- examples/Net/Gearman/Connection.php
|
34
|
+
- examples/Net/Gearman/Exception.php
|
35
|
+
- examples/Net/Gearman/Job.php
|
36
|
+
- examples/Net/Gearman/Job/Common.php
|
37
|
+
- examples/Net/Gearman/Job/Exception.php
|
38
|
+
- examples/Net/Gearman/Job/Sleep.php
|
39
|
+
- examples/Net/Gearman/Manager.php
|
40
|
+
- examples/Net/Gearman/Set.php
|
41
|
+
- examples/Net/Gearman/Task.php
|
42
|
+
- examples/Net/Gearman/Worker.php
|
43
|
+
- examples/client.php
|
44
|
+
- examples/client.rb
|
45
|
+
- examples/scale_image.rb
|
46
|
+
- examples/scale_image_worker.rb
|
47
|
+
- examples/server.rb
|
48
|
+
- examples/worker.php
|
49
|
+
- examples/worker.rb
|
50
|
+
- gearman-ruby.gemspec
|
51
|
+
- lib/gearman.rb
|
52
|
+
- lib/gearman/client.rb
|
53
|
+
- lib/gearman/server.rb
|
54
|
+
- lib/gearman/task.rb
|
55
|
+
- lib/gearman/taskset.rb
|
56
|
+
- lib/gearman/testlib.rb
|
57
|
+
- lib/gearman/util.rb
|
58
|
+
- lib/gearman/worker.rb
|
59
|
+
- test/client_test.rb
|
60
|
+
- test/mock_client_test.rb
|
61
|
+
- test/mock_worker_test.rb
|
62
|
+
- test/worker_test.rb
|
63
|
+
has_rdoc: true
|
64
|
+
homepage: http://github.com/xing/gearman-ruby
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options:
|
67
|
+
- --charset=UTF-8
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: "0"
|
75
|
+
version:
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.2.0
|
86
|
+
signing_key:
|
87
|
+
specification_version: 2
|
88
|
+
summary: Library for the Gearman distributed job system
|
89
|
+
test_files:
|
90
|
+
- test/client_test.rb
|
91
|
+
- test/mock_client_test.rb
|
92
|
+
- test/mock_worker_test.rb
|
93
|
+
- test/worker_test.rb
|
94
|
+
- examples/client.rb
|
95
|
+
- examples/scale_image.rb
|
96
|
+
- examples/scale_image_worker.rb
|
97
|
+
- examples/server.rb
|
98
|
+
- examples/worker.rb
|