gearman-ruby 3.0.4 → 3.0.6
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 +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
|