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.
@@ -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
@@ -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