gearman-ruby 3.0.4 → 3.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/CHANGELOG +3 -0
- data/Gemfile +7 -0
- data/HOWTO +1 -1
- data/Rakefile +14 -35
- data/VERSION.yml +1 -1
- data/examples/client.rb +1 -1
- data/gearman-ruby.gemspec +28 -0
- data/lib/gearman.rb +6 -0
- data/lib/gearman/client.rb +36 -19
- data/lib/gearman/server.rb +2 -2
- data/lib/gearman/task.rb +11 -3
- data/lib/gearman/taskset.rb +38 -31
- data/lib/gearman/util.rb +6 -3
- data/lib/gearman/version.rb +3 -0
- data/lib/gearman/worker.rb +73 -8
- data/spec/client_spec.rb +60 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/fake_tcp_socket.rb +25 -0
- data/spec/task_spec.rb +163 -0
- data/spec/taskset_spec.rb +79 -0
- data/spec/util_spec.rb +67 -0
- data/{lib/gearman → test}/testlib.rb +0 -0
- metadata +47 -65
data/.gitignore
CHANGED
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/HOWTO
CHANGED
data/Rakefile
CHANGED
@@ -1,40 +1,19 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require
|
4
|
-
|
5
|
-
|
6
|
-
begin
|
7
|
-
require 'jeweler'
|
8
|
-
Jeweler::Tasks.new do |s|
|
9
|
-
s.name = "gearman-ruby"
|
10
|
-
s.summary = "Library for the Gearman distributed job system"
|
11
|
-
s.email = "gearman.ruby@librelist.com"
|
12
|
-
s.homepage = "http://github.com/gearman-ruby/gearman-ruby"
|
13
|
-
s.description = "Library for the Gearman distributed job system"
|
14
|
-
s.authors = ["John Ewart", "Colin Curtin", "Daniel Erat", "Ladislav Martincik", "Pablo Delgado", "Mauro Pompilio", "Antonio Garrote", "Kim Altintop"]
|
15
|
-
end
|
16
|
-
rescue LoadError
|
17
|
-
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
18
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
Bundler::GemHelper.install_tasks
|
19
5
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Rake::RDocTask.new do |rdoc|
|
27
|
-
rdoc.rdoc_dir = 'rdoc'
|
28
|
-
rdoc.title = 'Gearman Ruby'
|
29
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
30
|
-
rdoc.rdoc_files.include('README*')
|
31
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
32
12
|
end
|
33
13
|
|
34
|
-
|
35
|
-
t.
|
36
|
-
t.
|
37
|
-
t.verbose = true
|
14
|
+
RSpec::Core::RakeTask.new do |t|
|
15
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
16
|
+
t.pattern = 'spec/**/*_spec.rb'
|
38
17
|
end
|
39
18
|
|
40
|
-
task :default => :
|
19
|
+
task :default => :spec
|
data/VERSION.yml
CHANGED
data/examples/client.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "gearman/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = %q{gearman-ruby}
|
6
|
+
s.version = Gearman::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["John Ewart", "Colin Curtin", "Daniel Erat", "Ladislav Martincik", "Pablo Delgado", "Mauro Pompilio", "Antonio Garrote", "Kim Altintop"]
|
9
|
+
s.date = %q{2013-07-25}
|
10
|
+
s.summary = %q{Ruby Gearman library}
|
11
|
+
s.description = %q{Library for the Gearman distributed job system}
|
12
|
+
s.email = %q{john@johnewart.net}
|
13
|
+
s.homepage = %q{http://github.com/johnewart/gearman-ruby}
|
14
|
+
s.rubyforge_project = "gearman-ruby"
|
15
|
+
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE",
|
18
|
+
"README",
|
19
|
+
"TODO"
|
20
|
+
]
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
end
|
28
|
+
|
data/lib/gearman.rb
CHANGED
data/lib/gearman/client.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
1
|
require 'socket'
|
4
2
|
|
5
3
|
module Gearman
|
@@ -18,13 +16,12 @@ class Client
|
|
18
16
|
self.job_servers = job_servers if job_servers
|
19
17
|
@sockets = {} # "host:port" -> [sock1, sock2, ...]
|
20
18
|
@socket_to_hostport = {} # sock -> "host:port"
|
21
|
-
@test_hostport = nil # make get_job_server return a given host for testing
|
22
19
|
@task_create_timeout_sec = 10
|
23
20
|
@server_counter = -1
|
24
21
|
@bad_servers = []
|
25
22
|
end
|
26
23
|
attr_reader :job_servers, :bad_servers
|
27
|
-
attr_accessor :
|
24
|
+
attr_accessor :task_create_timeout_sec
|
28
25
|
|
29
26
|
##
|
30
27
|
# Set the options
|
@@ -54,18 +51,37 @@ class Client
|
|
54
51
|
#
|
55
52
|
# @return "host:port"
|
56
53
|
def get_job_server
|
54
|
+
if @job_servers.empty? && !@bad_servers.empty?
|
55
|
+
Util.logger.debug "GearmanRuby: No more good job servers, trying bad ones: #{@bad_servers.inspect}."
|
56
|
+
# Try to reconnect to the bad servers
|
57
|
+
@bad_servers.each do |bad_server|
|
58
|
+
Util.logger.debug "GearmanRuby: Trying server: #{bad_server.inspect}"
|
59
|
+
begin
|
60
|
+
request = Util.pack_request("echo_req", "ping")
|
61
|
+
sock = self.get_socket(bad_server)
|
62
|
+
Util.send_request(sock, request)
|
63
|
+
response = Util.read_response(sock, 20)
|
64
|
+
if response[0] == :echo_res
|
65
|
+
@job_servers << bad_server
|
66
|
+
@bad_servers.delete bad_server
|
67
|
+
end
|
68
|
+
rescue NetworkError
|
69
|
+
Util.logger.debug "GearmanRuby: Error trying server: #{bad_server.inspect}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
57
73
|
|
58
|
-
|
59
|
-
|
74
|
+
Util.logger.debug "GearmanRuby: job servers: #{@job_servers.inspect}"
|
75
|
+
raise NoJobServersError if @job_servers.empty?
|
60
76
|
@server_counter += 1
|
61
|
-
|
62
|
-
@test_hostport or @job_servers[@server_counter % @job_servers.size]
|
77
|
+
@job_servers[@server_counter % @job_servers.size]
|
63
78
|
end
|
64
|
-
|
79
|
+
|
65
80
|
def signal_bad_server(hostport)
|
66
81
|
@job_servers = @job_servers.reject { |s| s == hostport }
|
67
82
|
@bad_servers << hostport
|
68
83
|
end
|
84
|
+
|
69
85
|
##
|
70
86
|
# Get a socket for a job server.
|
71
87
|
#
|
@@ -83,15 +99,14 @@ class Client
|
|
83
99
|
begin
|
84
100
|
sock = TCPSocket.new(*hostport.split(':'))
|
85
101
|
rescue Exception
|
102
|
+
# Swallow error so we can retry -> num_retries times
|
86
103
|
else
|
87
|
-
|
104
|
+
# No error, stash socket mapping and return it
|
88
105
|
@socket_to_hostport[sock] = hostport
|
89
106
|
return sock
|
90
107
|
end
|
91
108
|
end
|
92
|
-
|
93
|
-
signal_bad_server(hostport)
|
94
|
-
raise RuntimeError, "Unable to connect to job server #{hostport}"
|
109
|
+
raise NetworkError, "Unable to connect to job server #{hostport}"
|
95
110
|
end
|
96
111
|
|
97
112
|
##
|
@@ -103,9 +118,8 @@ class Client
|
|
103
118
|
def return_socket(sock)
|
104
119
|
hostport = get_hostport_for_socket(sock)
|
105
120
|
if not hostport
|
106
|
-
inet, port, host, ip =
|
107
|
-
Util.logger.error "GearmanRuby: Got socket for #{ip}:#{port}, which we don't "
|
108
|
-
"know about -- closing"
|
121
|
+
inet, port, host, ip = sock.addr
|
122
|
+
Util.logger.error "GearmanRuby: Got socket for #{ip}:#{port}, which we don't know about -- closing"
|
109
123
|
sock.close
|
110
124
|
return
|
111
125
|
end
|
@@ -141,12 +155,15 @@ class Client
|
|
141
155
|
task.on_fail { failed = true }
|
142
156
|
|
143
157
|
taskset = TaskSet.new(self)
|
144
|
-
taskset.add_task(task)
|
145
|
-
|
158
|
+
if taskset.add_task(task)
|
159
|
+
taskset.wait
|
160
|
+
else
|
161
|
+
raise JobQueueError, "Unable to enqueue job."
|
162
|
+
end
|
146
163
|
|
147
164
|
failed ? nil : result
|
148
165
|
end
|
149
166
|
|
150
167
|
end
|
151
168
|
|
152
|
-
end
|
169
|
+
end
|
data/lib/gearman/server.rb
CHANGED
@@ -48,7 +48,7 @@ class Server
|
|
48
48
|
while true do
|
49
49
|
if buf = socket.recv_nonblock(65536) rescue nil
|
50
50
|
response << buf
|
51
|
-
return response if response =~
|
51
|
+
return response if response =~ /^.$/
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -61,7 +61,7 @@ class Server
|
|
61
61
|
status = {}
|
62
62
|
if response = send_command('status')
|
63
63
|
response.split("\n").each do |line|
|
64
|
-
if line.match /^(
|
64
|
+
if line.match /^(.*)?\t(\d+)\t(\d+)\t(\d+)$/
|
65
65
|
(status[$1] ||= {})[$2] = { :queue => $3, :active => $4, :workers => $5 }
|
66
66
|
end
|
67
67
|
end
|
data/lib/gearman/task.rb
CHANGED
@@ -38,8 +38,7 @@ module Gearman
|
|
38
38
|
attr_reader :successful, :func, :arg, :retries_done
|
39
39
|
|
40
40
|
##
|
41
|
-
# Schedule this job to run at a certain time
|
42
|
-
# XXX: But there is no wildcard??
|
41
|
+
# Schedule this job to run at a certain time
|
43
42
|
#
|
44
43
|
# @param time Ruby Time object that represents when to run the thing
|
45
44
|
def schedule(time)
|
@@ -120,6 +119,15 @@ module Gearman
|
|
120
119
|
@on_complete.call(data) if @on_complete
|
121
120
|
self
|
122
121
|
end
|
122
|
+
|
123
|
+
def on_created(&f)
|
124
|
+
@on_created = f
|
125
|
+
end
|
126
|
+
|
127
|
+
def handle_created(data)
|
128
|
+
@on_created.call(data) if @on_created
|
129
|
+
self
|
130
|
+
end
|
123
131
|
|
124
132
|
##
|
125
133
|
# Record a failure and check whether we should be retried.
|
@@ -176,7 +184,7 @@ module Gearman
|
|
176
184
|
return @hash if @hash
|
177
185
|
|
178
186
|
if @uniq.nil?
|
179
|
-
string =
|
187
|
+
string = @func+@arg.to_s
|
180
188
|
else
|
181
189
|
string = @uniq
|
182
190
|
end
|
data/lib/gearman/taskset.rb
CHANGED
@@ -43,44 +43,47 @@ class TaskSet
|
|
43
43
|
req = task.get_submit_packet()
|
44
44
|
|
45
45
|
@task_waiting_for_handle = task
|
46
|
-
# FIXME: We need to loop here in case we get a bad job server, or the
|
47
|
-
# job creation fails (see how the server reports this to us), or ...
|
48
46
|
|
47
|
+
# Target the same job manager when submitting jobs
|
48
|
+
# with the same unique id so that we can coalesce
|
49
49
|
merge_hash = task.get_uniq_hash
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
should_try_rehash = true
|
54
|
-
while(looking_for_socket)
|
51
|
+
while (@task_waiting_for_handle != nil)
|
55
52
|
begin
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@client.get_job_server
|
60
|
-
end
|
53
|
+
# Try to connect again to the same server based on the unique hash
|
54
|
+
@merge_hash_to_hostport[merge_hash] ||= @client.get_job_server
|
55
|
+
hostport = @merge_hash_to_hostport[merge_hash]
|
61
56
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
begin
|
57
|
+
# Cache the socket
|
58
|
+
@sockets[hostport] ||= @client.get_socket(hostport)
|
59
|
+
|
60
|
+
# Submit job to server
|
61
|
+
sock = @sockets[hostport]
|
62
|
+
Util.logger.debug "GearmanRuby: Using socket #{sock.inspect} for #{hostport} to SUBMIT_JOB"
|
63
|
+
Util.send_request(sock, req)
|
64
|
+
|
65
|
+
# read_packet will fire off handle_job_created and set @task_waiting_for_handle to nil
|
66
|
+
# TODO: Better way of doing this.
|
73
67
|
read_packet(sock, @client.task_create_timeout_sec)
|
74
68
|
rescue NetworkError
|
75
|
-
Util.logger.debug "GearmanRuby:
|
76
|
-
|
77
|
-
@client.
|
69
|
+
Util.logger.debug "GearmanRuby: Network error on read from #{hostport} while adding job, marking server bad"
|
70
|
+
# Tell the client this is a bad server
|
71
|
+
@client.signal_bad_server(hostport)
|
72
|
+
if(sock != nil)
|
73
|
+
@client.close_socket(sock)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Un-cache socket
|
77
|
+
@sockets.delete hostport
|
78
|
+
# Remove from hash -> hostport mapping
|
79
|
+
@merge_hash_to_hostport[merge_hash] = nil
|
80
|
+
rescue NoJobServersError
|
81
|
+
Util.logger.error "GearmanRuby: No servers available."
|
78
82
|
return false
|
79
83
|
end
|
80
84
|
end
|
81
85
|
|
82
|
-
|
83
|
-
true
|
86
|
+
return true
|
84
87
|
end
|
85
88
|
private :add_task_internal
|
86
89
|
|
@@ -91,9 +94,11 @@ class TaskSet
|
|
91
94
|
# @param data data returned in packet from server
|
92
95
|
def handle_job_created(hostport, data)
|
93
96
|
Util.logger.debug "GearmanRuby: Got job_created with handle #{data} from #{hostport}"
|
97
|
+
|
94
98
|
if not @task_waiting_for_handle
|
95
|
-
raise ProtocolError, "Got unexpected job_created notification
|
99
|
+
raise ProtocolError, "Got unexpected job_created notification with handle #{data} from #{hostport}"
|
96
100
|
end
|
101
|
+
|
97
102
|
js_handle = Util.handle_to_str(hostport, data)
|
98
103
|
task = @task_waiting_for_handle
|
99
104
|
@task_waiting_for_handle = nil
|
@@ -102,6 +107,7 @@ class TaskSet
|
|
102
107
|
else
|
103
108
|
(@tasks_in_progress[js_handle] ||= []) << task
|
104
109
|
end
|
110
|
+
task.handle_created(data)
|
105
111
|
nil
|
106
112
|
end
|
107
113
|
private :handle_job_created
|
@@ -248,15 +254,16 @@ class TaskSet
|
|
248
254
|
@sockets = {}
|
249
255
|
return false
|
250
256
|
end
|
257
|
+
|
251
258
|
ready_socks[0].each do |sock|
|
252
259
|
begin
|
253
|
-
|
260
|
+
read_packet(sock, (end_time ? end_time - Time.now.to_f : nil))
|
254
261
|
rescue ProtocolError
|
255
262
|
hostport = @client.get_hostport_for_socket(sock)
|
256
263
|
Util.logger.debug "GearmanRuby: Ignoring bad packet from #{hostport}"
|
257
264
|
rescue NetworkError
|
258
265
|
hostport = @client.get_hostport_for_socket(sock)
|
259
|
-
Util.logger.debug "GearmanRuby:
|
266
|
+
Util.logger.debug "GearmanRuby: Network error on read from #{hostport}"
|
260
267
|
end
|
261
268
|
end
|
262
269
|
end
|
@@ -265,7 +272,7 @@ class TaskSet
|
|
265
272
|
@sockets = {}
|
266
273
|
@finished_tasks.each do |t|
|
267
274
|
if ( (t.background.nil? || t.background == false) && !t.successful)
|
268
|
-
Util.logger.debug "GearmanRuby:
|
275
|
+
Util.logger.debug "GearmanRuby: TaskSet failed"
|
269
276
|
return false
|
270
277
|
end
|
271
278
|
end
|
data/lib/gearman/util.rb
CHANGED
@@ -116,7 +116,11 @@ class Util
|
|
116
116
|
while data.size < len and (not timeout or Time.now.to_f < end_time) do
|
117
117
|
IO::select([sock], nil, nil, timeout ? end_time - Time.now.to_f : nil) \
|
118
118
|
or break
|
119
|
-
|
119
|
+
begin
|
120
|
+
data += sock.readpartial(len - data.size)
|
121
|
+
rescue
|
122
|
+
raise NetworkError, "Unable to read data from socket."
|
123
|
+
end
|
120
124
|
end
|
121
125
|
if data.size < len
|
122
126
|
raise NetworkError, "Read #{data.size} byte(s) instead of #{len}"
|
@@ -131,7 +135,6 @@ class Util
|
|
131
135
|
# @param timeout timeout in seconds, nil for no timeout
|
132
136
|
# @return array consisting of integer packet type and data
|
133
137
|
def Util.read_response(sock, timeout=nil)
|
134
|
-
#debugger
|
135
138
|
end_time = Time.now.to_f + timeout if timeout
|
136
139
|
head = timed_recv(sock, 12, timeout)
|
137
140
|
magic, type, len = head.unpack('a4NN')
|
@@ -184,7 +187,7 @@ class Util
|
|
184
187
|
# @return [hostport, handle]
|
185
188
|
def Util.str_to_handle(str)
|
186
189
|
str =~ %r{^([^:]+:\d+)//(.+)}
|
187
|
-
return [$1, $
|
190
|
+
return [$1, $2]
|
188
191
|
end
|
189
192
|
|
190
193
|
def self.with_safe_socket_op
|
data/lib/gearman/worker.rb
CHANGED
@@ -67,6 +67,7 @@ class Worker
|
|
67
67
|
#
|
68
68
|
# @param sock Socket connected to job server
|
69
69
|
# @param handle job server-supplied job handle
|
70
|
+
attr_reader :handle
|
70
71
|
def initialize(sock, handle)
|
71
72
|
@socket = sock
|
72
73
|
@handle = handle
|
@@ -98,6 +99,42 @@ class Worker
|
|
98
99
|
end
|
99
100
|
end
|
100
101
|
|
102
|
+
module Callbacks
|
103
|
+
|
104
|
+
%w(connect grab_job no_job job_assign work_complete work_fail
|
105
|
+
work_exception).each do |event|
|
106
|
+
|
107
|
+
define_method("on_#{event}") do |&callback|
|
108
|
+
instance_variable_set("@__on_#{event}", callback)
|
109
|
+
end
|
110
|
+
|
111
|
+
define_method("run_#{event}_callback") do
|
112
|
+
callback = instance_variable_get("@__on_#{event}")
|
113
|
+
return unless callback
|
114
|
+
|
115
|
+
begin
|
116
|
+
callback.call
|
117
|
+
rescue Exception => e
|
118
|
+
Util.logger.error "GearmanRuby: #{event} failed: #{e.inspect}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
# Provides callbacks for internal worker use:
|
126
|
+
#
|
127
|
+
# def named_metric(metric)
|
128
|
+
# "HardWorker.#{Process.pid}.#{metric}"
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# worker = Gearman::Worker.new
|
132
|
+
# worker.on_grab_job { StatsD.increment(named_metric('grab_job')) }
|
133
|
+
# worker.on_job_assign { StatsD.increment(named_metric('job_assign')) }
|
134
|
+
# worker.on_no_job { StatsD.increment(named_metric('no_job')) }
|
135
|
+
# worker.on_work_complete { StatsD.increment(named_metric('work_complete')) }
|
136
|
+
include Callbacks
|
137
|
+
|
101
138
|
##
|
102
139
|
# Create a new worker.
|
103
140
|
#
|
@@ -172,7 +209,7 @@ class Worker
|
|
172
209
|
# Disconnect from servers that we no longer care about.
|
173
210
|
@sockets.each do |server,sock|
|
174
211
|
if not servers.include? server
|
175
|
-
Util.logger.
|
212
|
+
Util.logger.info "GearmanRuby: Disconnecting from old server #{server}"
|
176
213
|
sock.close
|
177
214
|
@sockets.delete(server)
|
178
215
|
end
|
@@ -181,11 +218,12 @@ class Worker
|
|
181
218
|
servers.each do |server|
|
182
219
|
if not @sockets[server]
|
183
220
|
begin
|
184
|
-
Util.logger.
|
221
|
+
Util.logger.info "GearmanRuby: Connecting to server #{server}"
|
222
|
+
run_connect_callback
|
185
223
|
@sockets[server] = connect(server)
|
186
224
|
rescue NetworkError
|
187
225
|
@bad_servers << server
|
188
|
-
Util.logger.
|
226
|
+
Util.logger.info "GearmanRuby: Unable to connect to #{server}"
|
189
227
|
end
|
190
228
|
end
|
191
229
|
end
|
@@ -311,12 +349,15 @@ class Worker
|
|
311
349
|
cmd = if ret && exception.nil?
|
312
350
|
Util.logger.debug "GearmanRuby: Sending work_complete for #{handle} with #{ret.to_s.size} byte(s) " +
|
313
351
|
"to #{hostport}"
|
352
|
+
run_work_complete_callback
|
314
353
|
[ Util.pack_request(:work_complete, "#{handle}\0#{ret.to_s}") ]
|
315
354
|
elsif exception.nil?
|
316
355
|
Util.logger.debug "GearmanRuby: Sending work_fail for #{handle} to #{hostport}"
|
356
|
+
run_work_fail_callback
|
317
357
|
[ Util.pack_request(:work_fail, handle) ]
|
318
358
|
elsif exception
|
319
359
|
Util.logger.debug "GearmanRuby: Sending work_exception for #{handle} to #{hostport}"
|
360
|
+
run_work_exception_callback
|
320
361
|
[ Util.pack_request(:work_exception, "#{handle}\0#{exception.message}") ]
|
321
362
|
end
|
322
363
|
|
@@ -344,6 +385,8 @@ class Worker
|
|
344
385
|
# Do a single job and return.
|
345
386
|
def work
|
346
387
|
req = Util.pack_request(:grab_job)
|
388
|
+
type = nil
|
389
|
+
data = nil
|
347
390
|
loop do
|
348
391
|
@status = :preparing
|
349
392
|
bad_servers = []
|
@@ -353,6 +396,7 @@ class Worker
|
|
353
396
|
@servers_mutex.synchronize { servers = @sockets.keys.sort }
|
354
397
|
servers.each do |hostport|
|
355
398
|
Util.logger.debug "GearmanRuby: Sending grab_job to #{hostport}"
|
399
|
+
run_grab_job_callback
|
356
400
|
sock = @sockets[hostport]
|
357
401
|
Util.send_request(sock, req)
|
358
402
|
|
@@ -365,16 +409,18 @@ class Worker
|
|
365
409
|
case type
|
366
410
|
when :no_job
|
367
411
|
Util.logger.debug "GearmanRuby: Got no_job from #{hostport}"
|
412
|
+
run_no_job_callback
|
368
413
|
break
|
369
414
|
when :job_assign
|
370
415
|
@status = :working
|
416
|
+
run_job_assign_callback
|
371
417
|
return worker_enabled if handle_job_assign(data, sock, hostport)
|
372
418
|
break
|
373
419
|
else
|
374
420
|
Util.logger.debug "GearmanRuby: Got #{type.to_s} from #{hostport}"
|
375
421
|
end
|
376
422
|
rescue Exception
|
377
|
-
Util.logger.
|
423
|
+
Util.logger.info "GearmanRuby: Server #{hostport} timed out or lost connection (#{$!.inspect}); marking bad"
|
378
424
|
bad_servers << hostport
|
379
425
|
break
|
380
426
|
end
|
@@ -399,10 +445,29 @@ class Worker
|
|
399
445
|
return false unless worker_enabled
|
400
446
|
@status = :waiting
|
401
447
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
448
|
+
sleepTime = Time.now
|
449
|
+
while(@status == :waiting)
|
450
|
+
# FIXME: We could optimize things the next time through the 'each' by
|
451
|
+
# sending the first grab_job to one of the servers that had a socket
|
452
|
+
# with data in it. Not bothering with it for now.
|
453
|
+
IO::select(@sockets.values, nil, nil, @reconnect_sec)
|
454
|
+
|
455
|
+
# If 30 seconds have passed, then wakeup
|
456
|
+
@status = :wakeup if Time.now - sleepTime > 30
|
457
|
+
|
458
|
+
if(@status == :waiting)
|
459
|
+
@sockets.values.each do |sock|
|
460
|
+
type, data = Util.read_response(sock, @network_timeout_sec)
|
461
|
+
|
462
|
+
# there shouldn't be anything else here, if there is, we should be able to ignore it...
|
463
|
+
if(type == :noop)
|
464
|
+
Util.logger.debug "Received NoOp while sleeping... waking up!"
|
465
|
+
@status = :wakeup
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
406
471
|
end
|
407
472
|
end
|
408
473
|
end
|
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'socket'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/mocks'
|
5
|
+
require 'gearman'
|
6
|
+
|
7
|
+
describe Gearman::Client do
|
8
|
+
before(:all) do
|
9
|
+
@tcp_server = TCPServer.new 5789
|
10
|
+
@client = Gearman::Client.new(["localhost:5789"])
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
@tcp_server.close
|
15
|
+
end
|
16
|
+
|
17
|
+
it "creates a client" do
|
18
|
+
@client.should_not be nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it "creates a task set when you run a task" do
|
22
|
+
task_set = Gearman::TaskSet.new(@client)
|
23
|
+
Gearman::TaskSet.stub(:new).and_return task_set
|
24
|
+
task_set.should_receive(:add_task).and_return true
|
25
|
+
task_set.should_receive(:wait)
|
26
|
+
|
27
|
+
task = Gearman::Task.new("do_something", {:data => 123})
|
28
|
+
@client.do_task(task)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "raises an exception when submitting a job fails" do
|
32
|
+
task = Gearman::Task.new("queue", "data")
|
33
|
+
@client.should_receive(:get_job_server).and_raise Gearman::NoJobServersError
|
34
|
+
expect {
|
35
|
+
@client.do_task(task)
|
36
|
+
}.to raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it "gets a socket for the client's host:port combo" do
|
40
|
+
sock = @client.get_socket("localhost:5789")
|
41
|
+
sock.should_not be nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "closes sockets it doesn't know about when asked to return them" do
|
45
|
+
sock = double(TCPSocket)
|
46
|
+
sock.should_receive(:addr).and_return [nil, 1234, 'hostname', '1.2.3.4']
|
47
|
+
sock.should_receive(:close)
|
48
|
+
@client.return_socket(sock)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "properly emits an options request" do
|
52
|
+
Gearman::Util.should_receive(:send_request)
|
53
|
+
Gearman::Util.should_receive(:read_response).and_return([:error, "Snarf"])
|
54
|
+
expect {
|
55
|
+
@client.option_request("exceptions")
|
56
|
+
}.to raise_error
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class FakeTCPSocket
|
2
|
+
|
3
|
+
def readline(some_text = nil)
|
4
|
+
return @canned_response
|
5
|
+
end
|
6
|
+
|
7
|
+
def flush
|
8
|
+
end
|
9
|
+
|
10
|
+
def write(some_text = nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
def readchar
|
14
|
+
return 6
|
15
|
+
end
|
16
|
+
|
17
|
+
def read(num)
|
18
|
+
return num > @canned_response.size ? @canned_response : @canned_response[0..num]
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_canned(response)
|
22
|
+
@canned_response = response
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/spec/task_spec.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'socket'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/mocks'
|
5
|
+
require 'gearman'
|
6
|
+
|
7
|
+
describe Gearman::Task do
|
8
|
+
before(:each) do
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
context :creation do
|
13
|
+
it "throws an exception when passed bogus opts" do
|
14
|
+
expect {
|
15
|
+
Gearman::Task.new("bogus_task", "data", {:bogus => 'bogon'})
|
16
|
+
}.to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it "generates a uniq value based on the data and the function" do
|
20
|
+
hash_data = 'bc2ca93d86a28cb72fedf36326d1da0cc3d4ed6a'
|
21
|
+
task_one = Gearman::Task.new("unique_id", "abcdef")
|
22
|
+
expect(task_one.get_uniq_hash).to eq(hash_data)
|
23
|
+
|
24
|
+
task_two = Gearman::Task.new("unique_id", "foobar")
|
25
|
+
expect(task_two.get_uniq_hash).to_not eq(hash_data)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "honors a uniq value set for the task" do
|
29
|
+
task = Gearman::Task.new("unique_id", "abcdef", {:uniq => 'totally_awesome'})
|
30
|
+
expect(task.get_uniq_hash).to eq ('91aa6f67b66e394412d9be5f5699c843c726aad8')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context :get_submit_packet do
|
35
|
+
it "represents an EPOCH task properly" do
|
36
|
+
task = Gearman::Task.new("function", "data")
|
37
|
+
scheduled_for = Time.now
|
38
|
+
task.schedule(scheduled_for)
|
39
|
+
|
40
|
+
task_str = task.get_submit_packet
|
41
|
+
expect(task_str).to eq "\x00REQ\x00\x00\x00$\x00\x00\x00Afunction\x007dda232f7c04c9d59c0cc43e1c30dea72362e265\x00#{scheduled_for.to_i}\x00data"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "represents a background job properly" do
|
45
|
+
task = Gearman::BackgroundTask.new("background", "bgdata")
|
46
|
+
byte_string = "\x00REQ\x00\x00\x00\x12\x00\x00\x00:background\x00ed75b3f27f59d8e1ed51eedd3b5f98de3141ad49\x00bgdata"
|
47
|
+
expect(task.get_submit_packet).to eq byte_string
|
48
|
+
end
|
49
|
+
|
50
|
+
it "represents a high priority background job properly" do
|
51
|
+
task = Gearman::BackgroundTask.new("background", "highbgdata", {:priority => :high})
|
52
|
+
byte_string = "\x00REQ\x00\x00\x00 \x00\x00\x00>background\x003e304e4c11c31c904fbfae7b4f9840ef33006c5e\x00highbgdata"
|
53
|
+
expect(task.get_submit_packet).to eq byte_string
|
54
|
+
end
|
55
|
+
|
56
|
+
it "represents a low priority background job properly" do
|
57
|
+
task = Gearman::BackgroundTask.new("background", "lowbgdata", {:priority => :low})
|
58
|
+
byte_string = "\x00REQ\x00\x00\x00\"\x00\x00\x00=background\x0079f123e29effe921e32ce1600b2efc63ab716cad\x00lowbgdata"
|
59
|
+
expect(task.get_submit_packet).to eq byte_string
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
context :handle_responses do
|
66
|
+
before :each do
|
67
|
+
@task = Gearman::Task.new("handle_response", "some data")
|
68
|
+
end
|
69
|
+
|
70
|
+
it "calls handle_warning properly" do
|
71
|
+
warning_data = nil
|
72
|
+
@task.on_warning do |msg|
|
73
|
+
warning_data = msg
|
74
|
+
end
|
75
|
+
|
76
|
+
@task.handle_warning("message")
|
77
|
+
expect(warning_data).to eq "message"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "calls handle_status properly" do
|
81
|
+
numerator = nil
|
82
|
+
denominator = nil
|
83
|
+
|
84
|
+
@task.on_status do |n, d|
|
85
|
+
numerator = n
|
86
|
+
denominator = d
|
87
|
+
end
|
88
|
+
|
89
|
+
@task.handle_status(10, 100)
|
90
|
+
expect(numerator).to eq 10
|
91
|
+
expect(denominator).to eq 100
|
92
|
+
end
|
93
|
+
|
94
|
+
it "calls handle_failure correctly" do
|
95
|
+
error_message = nil
|
96
|
+
|
97
|
+
@task.on_fail do
|
98
|
+
error_message = "oops!"
|
99
|
+
end
|
100
|
+
|
101
|
+
@task.handle_failure
|
102
|
+
|
103
|
+
expect(error_message).to eq "oops!"
|
104
|
+
end
|
105
|
+
|
106
|
+
it "calls handle_data correctly" do
|
107
|
+
data_result = nil
|
108
|
+
|
109
|
+
@task.on_data do |data|
|
110
|
+
data_result = data
|
111
|
+
end
|
112
|
+
|
113
|
+
@task.handle_data("foonarf")
|
114
|
+
|
115
|
+
expect(data_result).to eq "foonarf"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "calls handle_created correctly" do
|
119
|
+
job_handle = nil
|
120
|
+
|
121
|
+
@task.on_created do |data|
|
122
|
+
job_handle = data
|
123
|
+
end
|
124
|
+
|
125
|
+
@task.handle_created("foonarf.local:1234")
|
126
|
+
|
127
|
+
expect(job_handle).to eq "foonarf.local:1234"
|
128
|
+
end
|
129
|
+
|
130
|
+
it "calls handle_exception correctly" do
|
131
|
+
exception_message = nil
|
132
|
+
|
133
|
+
@task.on_exception do |data|
|
134
|
+
exception_message = data
|
135
|
+
end
|
136
|
+
|
137
|
+
@task.handle_exception("NetworkError")
|
138
|
+
|
139
|
+
expect(exception_message).to eq "NetworkError"
|
140
|
+
end
|
141
|
+
|
142
|
+
it "retries if failure occurs and the failure count is greater than zero" do
|
143
|
+
retries_completed = 0
|
144
|
+
@task.retry_count = 5
|
145
|
+
@task.on_retry do |retries_done|
|
146
|
+
retries_completed = retries_done
|
147
|
+
end
|
148
|
+
@task.handle_failure.should == true
|
149
|
+
retries_completed.should == 1
|
150
|
+
end
|
151
|
+
|
152
|
+
it "does not retry if the number of retries completed has met the number of retries to execute" do
|
153
|
+
@task.retry_count = 3
|
154
|
+
retries_completed = 0
|
155
|
+
(0..@task.retry_count-1).each do |i|
|
156
|
+
retries_completed += 1
|
157
|
+
@task.handle_failure.should == true
|
158
|
+
end
|
159
|
+
@task.handle_failure.should == false
|
160
|
+
retries_completed.should == 3
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'socket'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/mocks'
|
5
|
+
require 'gearman'
|
6
|
+
|
7
|
+
describe Gearman::TaskSet do
|
8
|
+
before do
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
it "handles a NetworkError when submitting a job" do
|
17
|
+
bad_socket = double(TCPSocket)
|
18
|
+
bad_socket.should_receive(:write) { |*args|
|
19
|
+
args[0].length
|
20
|
+
}.at_least(:once)
|
21
|
+
bad_socket.should_receive(:close)
|
22
|
+
|
23
|
+
good_socket = double(TCPSocket)
|
24
|
+
good_socket.should_receive(:write) { |*args|
|
25
|
+
args[0].length
|
26
|
+
}.at_least(:once)
|
27
|
+
|
28
|
+
Gearman::Util.should_receive(:timed_recv).with(bad_socket, 12, anything).and_raise Gearman::NetworkError
|
29
|
+
Gearman::Util.should_receive(:timed_recv).with(good_socket, 12, anything).and_return("\x00RES\x00\x00\x00\x08\000\000\000\007")
|
30
|
+
Gearman::Util.should_receive(:timed_recv).with(good_socket, 7, anything).and_return("foo:123")
|
31
|
+
|
32
|
+
client = Gearman::Client.new(["localhost:4731", "localhost:4732"])
|
33
|
+
client.should_receive(:get_hostport_for_socket).at_least(1).times.with(bad_socket).and_return "localhost:4731"
|
34
|
+
client.should_receive(:get_hostport_for_socket).at_least(1).times.with(good_socket).and_return "localhost:4732"
|
35
|
+
client.should_receive(:get_socket).with("localhost:4731").and_return bad_socket
|
36
|
+
client.should_receive(:get_socket).with("localhost:4732").and_return good_socket
|
37
|
+
|
38
|
+
task = Gearman::Task.new("job_queue", "data")
|
39
|
+
|
40
|
+
task_set = Gearman::TaskSet.new(client)
|
41
|
+
task_set.add_task(task)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "waits for an answer from the server" do
|
45
|
+
good_socket = double(TCPSocket)
|
46
|
+
good_socket.should_receive(:write) { |*args|
|
47
|
+
args[0].length
|
48
|
+
}.at_least(:once)
|
49
|
+
|
50
|
+
Gearman::Util.should_receive(:timed_recv).with(good_socket, 12, anything).and_return("\x00RES\x00\x00\x00\x08\000\000\000\007")
|
51
|
+
Gearman::Util.should_receive(:timed_recv).with(good_socket, 7, anything).and_return("foo:123")
|
52
|
+
|
53
|
+
client = Gearman::Client.new(["localhost:4731"])
|
54
|
+
client.should_receive(:get_hostport_for_socket).at_least(1).times.with(good_socket).and_return "localhost:4731"
|
55
|
+
client.should_receive(:get_socket).with("localhost:4731").and_return good_socket
|
56
|
+
|
57
|
+
task = Gearman::Task.new("job_queue", "data")
|
58
|
+
|
59
|
+
task_set = Gearman::TaskSet.new(client)
|
60
|
+
task_set.add_task(task)
|
61
|
+
|
62
|
+
Gearman::Util.should_receive(:timed_recv).with(good_socket, 12, anything) {
|
63
|
+
sleep 0.5
|
64
|
+
"\x00RES\x00\x00\x00\x0d\000\000\000\007"
|
65
|
+
}
|
66
|
+
|
67
|
+
Gearman::Util.should_receive(:timed_recv).with(good_socket, 7, anything) {
|
68
|
+
"foo:123"
|
69
|
+
}
|
70
|
+
|
71
|
+
IO.stub(:select).and_return([[good_socket]])
|
72
|
+
start_time = Time.now
|
73
|
+
task_set.wait(30)
|
74
|
+
time_diff = Time.now - start_time
|
75
|
+
time_diff.should be < 30
|
76
|
+
time_diff.should be > 0
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
data/spec/util_spec.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'socket'
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec/mocks'
|
5
|
+
require 'gearman'
|
6
|
+
|
7
|
+
describe Gearman::Util do
|
8
|
+
before(:each) do
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should generate a task from two arguments" do
|
13
|
+
task = Gearman::Util.get_task_from_args("queue", "data")
|
14
|
+
task.should_not be nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should generate a task from three arguments" do
|
18
|
+
task = Gearman::Util.get_task_from_args("queue", "data", {:background => true})
|
19
|
+
task.should_not be nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should raise an exception with more than three arguments" do
|
23
|
+
expect {
|
24
|
+
Gearman::Util.get_task_from_args("one", "two", {:three => :four}, :five)
|
25
|
+
}.to raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise a NetworkError when it didn't write as much as expected to a socket" do
|
29
|
+
socket = double(TCPSocket)
|
30
|
+
socket.should_receive(:write).with(anything).and_return(0)
|
31
|
+
|
32
|
+
task = Gearman::Task.new("job_queue", "data")
|
33
|
+
request = task.get_submit_packet
|
34
|
+
expect {
|
35
|
+
Gearman::Util.send_request(socket, request)
|
36
|
+
}.to raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
context "normalizing job servers" do
|
40
|
+
it "should handle a string for input" do
|
41
|
+
Gearman::Util.normalize_job_servers("localhost:1234").should eq ["localhost:1234"]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should handle an array of host:port without changing a thing" do
|
45
|
+
servers = ["localhost:123", "localhost:456"]
|
46
|
+
Gearman::Util.normalize_job_servers(servers).should eq servers
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should append the default port to anything in the array that doesn't have a port" do
|
50
|
+
in_servers = ["foo.bar.com:123", "narf.quiddle.com"]
|
51
|
+
out_servers = ["foo.bar.com:123", "narf.quiddle.com:4730"]
|
52
|
+
Gearman::Util.normalize_job_servers(in_servers).should eq out_servers
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should convert a host:port & handle into its corresponding string" do
|
57
|
+
Gearman::Util.handle_to_str("localhost:4730", "foo:1").should eq "localhost:4730//foo:1"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should convert a host:port & handle string into its components" do
|
61
|
+
Gearman::Util.str_to_handle("localhost:4730//foo:1").should eq ["localhost:4730", "foo:1"]
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should convert an ability name with prefix into its correct format" do
|
65
|
+
Gearman::Util.ability_name_with_prefix("test", "a").should eq "test\ta"
|
66
|
+
end
|
67
|
+
end
|
File without changes
|
metadata
CHANGED
@@ -1,15 +1,10 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: gearman-ruby
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 3
|
8
|
-
- 0
|
9
|
-
- 4
|
10
|
-
version: 3.0.4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 3.0.6
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- John Ewart
|
14
9
|
- Colin Curtin
|
15
10
|
- Daniel Erat
|
@@ -21,22 +16,20 @@ authors:
|
|
21
16
|
autorequire:
|
22
17
|
bindir: bin
|
23
18
|
cert_chain: []
|
24
|
-
|
25
|
-
date: 2010-12-17 00:00:00 -08:00
|
26
|
-
default_executable:
|
19
|
+
date: 2013-07-25 00:00:00.000000000 Z
|
27
20
|
dependencies: []
|
28
|
-
|
29
21
|
description: Library for the Gearman distributed job system
|
30
|
-
email:
|
22
|
+
email: john@johnewart.net
|
31
23
|
executables: []
|
32
|
-
|
33
24
|
extensions: []
|
34
|
-
|
35
|
-
extra_rdoc_files:
|
25
|
+
extra_rdoc_files:
|
36
26
|
- LICENSE
|
37
27
|
- README
|
38
|
-
|
28
|
+
- TODO
|
29
|
+
files:
|
39
30
|
- .gitignore
|
31
|
+
- CHANGELOG
|
32
|
+
- Gemfile
|
40
33
|
- HOWTO
|
41
34
|
- LICENSE
|
42
35
|
- README
|
@@ -64,75 +57,64 @@ files:
|
|
64
57
|
- examples/worker_reverse_string.rb
|
65
58
|
- examples/worker_reverse_to_file.rb
|
66
59
|
- examples/worker_signals.rb
|
60
|
+
- gearman-ruby.gemspec
|
67
61
|
- lib/gearman.rb
|
68
62
|
- lib/gearman/client.rb
|
69
63
|
- lib/gearman/server.rb
|
70
64
|
- lib/gearman/task.rb
|
71
65
|
- lib/gearman/taskset.rb
|
72
|
-
- lib/gearman/testlib.rb
|
73
66
|
- lib/gearman/util.rb
|
67
|
+
- lib/gearman/version.rb
|
74
68
|
- lib/gearman/worker.rb
|
69
|
+
- spec/client_spec.rb
|
70
|
+
- spec/spec_helper.rb
|
71
|
+
- spec/support/fake_tcp_socket.rb
|
72
|
+
- spec/task_spec.rb
|
73
|
+
- spec/taskset_spec.rb
|
74
|
+
- spec/util_spec.rb
|
75
75
|
- test/client_test.rb
|
76
76
|
- test/mock_client_test.rb
|
77
77
|
- test/mock_worker_test.rb
|
78
|
+
- test/testlib.rb
|
78
79
|
- test/util_test.rb
|
79
80
|
- test/worker_test.rb
|
80
|
-
|
81
|
-
homepage: http://github.com/gearman-ruby/gearman-ruby
|
81
|
+
homepage: http://github.com/johnewart/gearman-ruby
|
82
82
|
licenses: []
|
83
|
-
|
84
83
|
post_install_message:
|
85
|
-
rdoc_options:
|
86
|
-
|
87
|
-
require_paths:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
88
86
|
- lib
|
89
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
88
|
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
segments:
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
segments:
|
96
94
|
- 0
|
97
|
-
|
98
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
hash: -888361438356632818
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
97
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
|
104
|
-
segments:
|
105
|
-
- 0
|
106
|
-
version: "0"
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
107
102
|
requirements: []
|
108
|
-
|
109
|
-
|
110
|
-
rubygems_version: 1.3.7
|
103
|
+
rubyforge_project: gearman-ruby
|
104
|
+
rubygems_version: 1.8.23
|
111
105
|
signing_key:
|
112
106
|
specification_version: 3
|
113
|
-
summary:
|
114
|
-
test_files:
|
107
|
+
summary: Ruby Gearman library
|
108
|
+
test_files:
|
109
|
+
- spec/client_spec.rb
|
110
|
+
- spec/spec_helper.rb
|
111
|
+
- spec/support/fake_tcp_socket.rb
|
112
|
+
- spec/task_spec.rb
|
113
|
+
- spec/taskset_spec.rb
|
114
|
+
- spec/util_spec.rb
|
115
115
|
- test/client_test.rb
|
116
116
|
- test/mock_client_test.rb
|
117
117
|
- test/mock_worker_test.rb
|
118
|
+
- test/testlib.rb
|
118
119
|
- test/util_test.rb
|
119
120
|
- test/worker_test.rb
|
120
|
-
- examples/calculus_client.rb
|
121
|
-
- examples/calculus_worker.rb
|
122
|
-
- examples/client.rb
|
123
|
-
- examples/client_background.rb
|
124
|
-
- examples/client_data.rb
|
125
|
-
- examples/client_epoch.rb
|
126
|
-
- examples/client_exception.rb
|
127
|
-
- examples/client_prefix.rb
|
128
|
-
- examples/client_reverse.rb
|
129
|
-
- examples/scale_image.rb
|
130
|
-
- examples/scale_image_worker.rb
|
131
|
-
- examples/server.rb
|
132
|
-
- examples/worker.rb
|
133
|
-
- examples/worker_data.rb
|
134
|
-
- examples/worker_exception.rb
|
135
|
-
- examples/worker_prefix.rb
|
136
|
-
- examples/worker_reverse_string.rb
|
137
|
-
- examples/worker_reverse_to_file.rb
|
138
|
-
- examples/worker_signals.rb
|