gearman-ruby 3.0.8 → 4.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +5 -0
- data/CHANGELOG.md +6 -4
- data/README.md +111 -0
- data/examples/client.rb +1 -2
- data/examples/client_reverse_nohost.rb +30 -0
- data/examples/{client_reverse.rb → client_reverse_wait.rb} +9 -11
- data/examples/worker.rb +8 -5
- data/examples/worker_reverse_string.rb +12 -17
- data/gearman-ruby.gemspec +3 -5
- data/lib/gearman.rb +17 -77
- data/lib/gearman/client.rb +129 -147
- data/lib/gearman/connection.rb +158 -0
- data/lib/gearman/connection_pool.rb +131 -0
- data/lib/gearman/exceptions.rb +24 -0
- data/lib/gearman/logging.rb +19 -0
- data/lib/gearman/packet.rb +61 -0
- data/lib/gearman/task.rb +1 -1
- data/lib/gearman/task_set.rb +67 -0
- data/lib/gearman/version.rb +1 -1
- data/lib/gearman/worker.rb +185 -412
- data/lib/gearman/worker/ability.rb +55 -0
- data/lib/gearman/worker/callbacks.rb +39 -0
- data/lib/gearman/worker/job.rb +44 -0
- data/spec/client_spec.rb +32 -20
- data/spec/connection_pool_spec.rb +55 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/task_spec.rb +10 -0
- data/spec/taskset_spec.rb +2 -2
- metadata +18 -37
- data/HOWTO +0 -146
- data/README +0 -9
- data/TODO +0 -8
- data/VERSION.yml +0 -4
- data/examples/calculus_client.rb +0 -39
- data/examples/calculus_worker.rb +0 -45
- data/examples/client.php +0 -23
- data/examples/client_background.rb +0 -14
- data/examples/client_data.rb +0 -16
- data/examples/client_epoch.rb +0 -23
- data/examples/client_exception.rb +0 -19
- data/examples/client_prefix.rb +0 -17
- data/examples/gearman_environment.sh +0 -25
- data/examples/scale_image.rb +0 -31
- data/examples/scale_image_worker.rb +0 -34
- data/examples/server.rb +0 -15
- data/examples/worker_data.rb +0 -16
- data/examples/worker_exception.rb +0 -14
- data/examples/worker_prefix.rb +0 -25
- data/examples/worker_reverse_to_file.rb +0 -18
- data/examples/worker_signals.rb +0 -36
- data/lib/gearman/taskset.rb +0 -293
- data/lib/gearman/util.rb +0 -211
- data/spec/util_spec.rb +0 -67
data/lib/gearman/taskset.rb
DELETED
@@ -1,293 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'socket'
|
4
|
-
require 'time'
|
5
|
-
|
6
|
-
module Gearman
|
7
|
-
|
8
|
-
# = TaskSet
|
9
|
-
#
|
10
|
-
# == Description
|
11
|
-
# A set of tasks submitted to a Gearman job server.
|
12
|
-
class TaskSet
|
13
|
-
def initialize(client)
|
14
|
-
@client = client
|
15
|
-
@task_waiting_for_handle = nil
|
16
|
-
@tasks_in_progress = {} # "host:port//handle" -> [job1, job2, ...]
|
17
|
-
@finished_tasks = [] # tasks that have completed or failed
|
18
|
-
@sockets = {} # "host:port" -> Socket
|
19
|
-
@merge_hash_to_hostport = {} # Fixnum -> "host:port"
|
20
|
-
end
|
21
|
-
|
22
|
-
##
|
23
|
-
# Add a new task to this TaskSet.
|
24
|
-
#
|
25
|
-
# @param args either a Task or arguments for Task.new
|
26
|
-
# @return true if the task was created successfully, false otherwise
|
27
|
-
def add_task(*args)
|
28
|
-
task = Util::get_task_from_args(*args)
|
29
|
-
add_task_internal(task, true)
|
30
|
-
end
|
31
|
-
|
32
|
-
##
|
33
|
-
# Internal function to add a task.
|
34
|
-
#
|
35
|
-
# @param task Task to add
|
36
|
-
# @param reset_state should we reset task state? true if we're adding a
|
37
|
-
# new task; false if we're rescheduling one that's
|
38
|
-
# failed
|
39
|
-
# @return true if the task was created successfully, false
|
40
|
-
# otherwise
|
41
|
-
def add_task_internal(task, reset_state=true)
|
42
|
-
task.reset_state if reset_state
|
43
|
-
req = task.get_submit_packet()
|
44
|
-
|
45
|
-
@task_waiting_for_handle = task
|
46
|
-
|
47
|
-
# Target the same job manager when submitting jobs
|
48
|
-
# with the same unique id so that we can coalesce
|
49
|
-
merge_hash = task.get_uniq_hash
|
50
|
-
|
51
|
-
while (@task_waiting_for_handle != nil)
|
52
|
-
begin
|
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]
|
56
|
-
|
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.
|
67
|
-
read_packet(sock, @client.task_create_timeout_sec)
|
68
|
-
rescue NetworkError
|
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."
|
82
|
-
return false
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
return true
|
87
|
-
end
|
88
|
-
private :add_task_internal
|
89
|
-
|
90
|
-
##
|
91
|
-
# Handle a 'job_created' response from a job server.
|
92
|
-
#
|
93
|
-
# @param hostport "host:port" of job server
|
94
|
-
# @param data data returned in packet from server
|
95
|
-
def handle_job_created(hostport, data)
|
96
|
-
Util.logger.debug "GearmanRuby: Got job_created with handle #{data} from #{hostport}"
|
97
|
-
|
98
|
-
if not @task_waiting_for_handle
|
99
|
-
raise ProtocolError, "Got unexpected job_created notification with handle #{data} from #{hostport}"
|
100
|
-
end
|
101
|
-
|
102
|
-
js_handle = Util.handle_to_str(hostport, data)
|
103
|
-
task = @task_waiting_for_handle
|
104
|
-
@task_waiting_for_handle = nil
|
105
|
-
if(task.background)
|
106
|
-
@finished_tasks << task
|
107
|
-
else
|
108
|
-
(@tasks_in_progress[js_handle] ||= []) << task
|
109
|
-
end
|
110
|
-
task.handle_created(data)
|
111
|
-
nil
|
112
|
-
end
|
113
|
-
private :handle_job_created
|
114
|
-
|
115
|
-
##
|
116
|
-
# Handle a 'work_complete' response from a job server.
|
117
|
-
#
|
118
|
-
# @param hostport "host:port" of job server
|
119
|
-
# @param data data returned in packet from server
|
120
|
-
def handle_work_complete(hostport, data)
|
121
|
-
handle, data = data.split("\0", 2)
|
122
|
-
Util.logger.debug "GearmanRuby: Got work_complete with handle #{handle} and #{data ? data.size : '0'} byte(s) of data from #{hostport}"
|
123
|
-
tasks_in_progress(hostport, handle, true).each do |t|
|
124
|
-
t.handle_completion(data)
|
125
|
-
@finished_tasks << t
|
126
|
-
end
|
127
|
-
nil
|
128
|
-
end
|
129
|
-
private :handle_work_complete
|
130
|
-
|
131
|
-
##
|
132
|
-
# Handle a 'work_exception' response from a job server.
|
133
|
-
#
|
134
|
-
# @param hostport "host:port" of job server
|
135
|
-
# @param data data returned in packet from server
|
136
|
-
def handle_work_exception(hostport, data)
|
137
|
-
handle, exception = data.split("\0", 2)
|
138
|
-
Util.logger.debug "GearmanRuby: Got work_exception with handle #{handle} from #{hostport}: '#{exception}'"
|
139
|
-
tasks_in_progress(hostport, handle).each {|t| t.handle_exception(exception) }
|
140
|
-
end
|
141
|
-
private :handle_work_exception
|
142
|
-
|
143
|
-
##
|
144
|
-
# Handle a 'work_fail' response from a job server.
|
145
|
-
#
|
146
|
-
# @param hostport "host:port" of job server
|
147
|
-
# @param data data returned in packet from server
|
148
|
-
def handle_work_fail(hostport, data)
|
149
|
-
Util.logger.debug "GearmanRuby: Got work_fail with handle #{data} from #{hostport}"
|
150
|
-
tasks_in_progress(hostport, data, true).each do |t|
|
151
|
-
if t.handle_failure
|
152
|
-
add_task_internal(t, false)
|
153
|
-
else
|
154
|
-
@finished_tasks << t
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
private :handle_work_fail
|
159
|
-
|
160
|
-
##
|
161
|
-
# Handle a 'work_status' response from a job server.
|
162
|
-
#
|
163
|
-
# @param hostport "host:port" of job server
|
164
|
-
# @param data data returned in packet from server
|
165
|
-
def handle_work_status(hostport, data)
|
166
|
-
handle, num, den = data.split("\0", 3)
|
167
|
-
Util.logger.debug "GearmanRuby: Got work_status with handle #{handle} from #{hostport}: #{num}/#{den}"
|
168
|
-
tasks_in_progress(hostport, handle).each {|t| t.handle_status(num, den) }
|
169
|
-
end
|
170
|
-
private :handle_work_status
|
171
|
-
|
172
|
-
##
|
173
|
-
# Handle a 'work_warning' response from a job server.
|
174
|
-
#
|
175
|
-
# @param hostport "host:port" of job server
|
176
|
-
# @param data data returned in packet from server
|
177
|
-
def handle_work_warning(hostport, data)
|
178
|
-
handle, message = data.split("\0", 2)
|
179
|
-
Util.logger.debug "GearmanRuby: Got work_warning with handle #{handle} from #{hostport}: '#{message}'"
|
180
|
-
tasks_in_progress(hostport, handle).each {|t| t.handle_warning(message) }
|
181
|
-
end
|
182
|
-
private :handle_work_warning
|
183
|
-
|
184
|
-
##
|
185
|
-
# Handle a 'work_data' response from a job server
|
186
|
-
#
|
187
|
-
# @param hostport "host:port" of a job server
|
188
|
-
# @param data data returned in packet from server
|
189
|
-
def handle_work_data(hostport, data)
|
190
|
-
handle, data = data.split("\0", 2)
|
191
|
-
Util.logger.debug "GearmanRuby: Got work_data with handle #{handle} and #{data ? data.size : '0'} byte(s) of data from #{hostport}"
|
192
|
-
|
193
|
-
js_handle = Util.handle_to_str(hostport, handle)
|
194
|
-
tasks = @tasks_in_progress[js_handle]
|
195
|
-
if not tasks
|
196
|
-
raise ProtocolError, "Got unexpected work_data with handle #{handle} from #{hostport} (no task by that name)"
|
197
|
-
end
|
198
|
-
tasks.each {|t| t.handle_data(data) }
|
199
|
-
end
|
200
|
-
private :handle_work_data
|
201
|
-
|
202
|
-
##
|
203
|
-
# Read and process a packet from a socket.
|
204
|
-
#
|
205
|
-
# @param sock socket connected to a job server
|
206
|
-
def read_packet(sock, timeout=nil)
|
207
|
-
hostport = @client.get_hostport_for_socket(sock)
|
208
|
-
if not hostport
|
209
|
-
raise RuntimeError, "Client doesn't know host/port for socket " +
|
210
|
-
sock.inspect
|
211
|
-
end
|
212
|
-
type, data = Util.read_response(sock, timeout)
|
213
|
-
known_types = [ :job_created,
|
214
|
-
:work_complete,
|
215
|
-
:work_fail,
|
216
|
-
:work_status,
|
217
|
-
:work_exception,
|
218
|
-
:work_warning,
|
219
|
-
:work_data ]
|
220
|
-
|
221
|
-
if known_types.include?(type)
|
222
|
-
send("handle_#{type}".to_sym, hostport, data)
|
223
|
-
else
|
224
|
-
Util.logger.debug "GearmanRuby: Got #{type.to_s} from #{hostport}"
|
225
|
-
end
|
226
|
-
nil
|
227
|
-
end
|
228
|
-
private :read_packet
|
229
|
-
|
230
|
-
##
|
231
|
-
# Wait for all tasks in the set to finish.
|
232
|
-
#
|
233
|
-
# @param timeout maximum amount of time to wait, in seconds
|
234
|
-
def wait(timeout = 1)
|
235
|
-
end_time = if timeout
|
236
|
-
Time.now.to_f + timeout
|
237
|
-
else
|
238
|
-
nil
|
239
|
-
end
|
240
|
-
|
241
|
-
while not @tasks_in_progress.empty?
|
242
|
-
remaining = if end_time
|
243
|
-
(t = end_time - Time.now.to_f) > 0 ? t : 0
|
244
|
-
else
|
245
|
-
nil
|
246
|
-
end
|
247
|
-
|
248
|
-
ready_socks = remaining == 0 ? nil : IO::select(@sockets.values, nil, nil, remaining)
|
249
|
-
if not ready_socks or not ready_socks[0]
|
250
|
-
Util.logger.debug "GearmanRuby: Timed out while waiting for tasks to finish"
|
251
|
-
# not sure what state the connections are in, so just be lame and
|
252
|
-
# close them for now
|
253
|
-
@sockets.values.each {|s| @client.close_socket(s) }
|
254
|
-
@sockets = {}
|
255
|
-
return false
|
256
|
-
end
|
257
|
-
|
258
|
-
ready_socks[0].each do |sock|
|
259
|
-
begin
|
260
|
-
read_packet(sock, (end_time ? end_time - Time.now.to_f : nil))
|
261
|
-
rescue ProtocolError
|
262
|
-
hostport = @client.get_hostport_for_socket(sock)
|
263
|
-
Util.logger.debug "GearmanRuby: Ignoring bad packet from #{hostport}"
|
264
|
-
rescue NetworkError
|
265
|
-
hostport = @client.get_hostport_for_socket(sock)
|
266
|
-
Util.logger.debug "GearmanRuby: Network error on read from #{hostport}"
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
@sockets.values.each {|s| @client.return_socket(s) }
|
272
|
-
@sockets = {}
|
273
|
-
@finished_tasks.each do |t|
|
274
|
-
if ( (t.background.nil? || t.background == false) && !t.successful)
|
275
|
-
Util.logger.debug "GearmanRuby: TaskSet failed"
|
276
|
-
return false
|
277
|
-
end
|
278
|
-
end
|
279
|
-
true
|
280
|
-
end
|
281
|
-
|
282
|
-
private
|
283
|
-
def tasks_in_progress(hostport, handle, remove_task = false)
|
284
|
-
js_handle = Util.handle_to_str(hostport, handle)
|
285
|
-
tasks = remove_task ? @tasks_in_progress.delete(js_handle) : @tasks_in_progress[js_handle]
|
286
|
-
if not tasks
|
287
|
-
raise ProtocolError, "Got unexpected work_data with handle #{handle} from #{hostport} (no task by that name)"
|
288
|
-
end
|
289
|
-
tasks
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
end
|
data/lib/gearman/util.rb
DELETED
@@ -1,211 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'socket'
|
4
|
-
require 'time'
|
5
|
-
require 'logger'
|
6
|
-
|
7
|
-
module Gearman
|
8
|
-
|
9
|
-
class ServerDownException < Exception; end
|
10
|
-
|
11
|
-
# = Util
|
12
|
-
#
|
13
|
-
# == Description
|
14
|
-
# Static helper methods and data used by other classes.
|
15
|
-
class Util
|
16
|
-
# Map from Integer representations of commands used in the network
|
17
|
-
# protocol to more-convenient symbols.
|
18
|
-
COMMANDS = {
|
19
|
-
1 => :can_do, # W->J: FUNC
|
20
|
-
2 => :cant_do, # W->J: FUNC
|
21
|
-
3 => :reset_abilities, # W->J: --
|
22
|
-
4 => :pre_sleep, # W->J: --
|
23
|
-
#5 => (unused), # - -
|
24
|
-
6 => :noop, # J->W: --
|
25
|
-
7 => :submit_job, # C->J: FUNC[0]UNIQ[0]ARGS
|
26
|
-
8 => :job_created, # J->C: HANDLE
|
27
|
-
9 => :grab_job, # W->J: --
|
28
|
-
10 => :no_job, # J->W: --
|
29
|
-
11 => :job_assign, # J->W: HANDLE[0]FUNC[0]ARG
|
30
|
-
12 => :work_status, # W->J/C: HANDLE[0]NUMERATOR[0]DENOMINATOR
|
31
|
-
13 => :work_complete, # W->J/C: HANDLE[0]RES
|
32
|
-
14 => :work_fail, # W->J/C: HANDLE
|
33
|
-
15 => :get_status, # C->J: HANDLE
|
34
|
-
16 => :echo_req, # ?->J: TEXT
|
35
|
-
17 => :echo_res, # J->?: TEXT
|
36
|
-
18 => :submit_job_bg, # C->J: FUNC[0]UNIQ[0]ARGS
|
37
|
-
19 => :error, # J->?: ERRCODE[0]ERR_TEXT
|
38
|
-
20 => :status_res, # C->J: HANDLE[0]KNOWN[0]RUNNING[0]NUM[0]DENOM
|
39
|
-
21 => :submit_job_high, # C->J: FUNC[0]UNIQ[0]ARGS
|
40
|
-
22 => :set_client_id, # W->J: [RANDOM_STRING_NO_WHITESPACE]
|
41
|
-
23 => :can_do_timeout, # W->J: FUNC[0]TIMEOUT
|
42
|
-
24 => :all_yours, # REQ Worker
|
43
|
-
25 => :work_exception, # W->J: HANDLE[0]ARG
|
44
|
-
26 => :option_req, # C->J: TEXT
|
45
|
-
27 => :option_res, # J->C: TEXT
|
46
|
-
28 => :work_data, # REQ Worker
|
47
|
-
29 => :work_warning, # W->J/C: HANDLE[0]MSG
|
48
|
-
30 => :grab_job_uniq, # REQ Worker
|
49
|
-
31 => :job_assign_uniq, # RES Worker
|
50
|
-
32 => :submit_job_high_bg, # C->J: FUNC[0]UNIQ[0]ARGS
|
51
|
-
33 => :submit_job_low, # C->J: FUNC[0]UNIQ[0]ARGS
|
52
|
-
34 => :submit_job_low_bg, # C->J: FUNC[0]UNIQ[0]ARGS
|
53
|
-
35 => :submit_job_sched, # REQ Client
|
54
|
-
36 => :submit_job_epoch # C->J: FUNC[0]UNIQ[0]EPOCH[0]ARGS
|
55
|
-
}
|
56
|
-
|
57
|
-
# Map e.g. 'can_do' => 1
|
58
|
-
NUMS = COMMANDS.invert
|
59
|
-
|
60
|
-
# Default job server port.
|
61
|
-
DEFAULT_PORT = 4730
|
62
|
-
|
63
|
-
def Util.logger=(logger)
|
64
|
-
@logger = logger
|
65
|
-
end
|
66
|
-
|
67
|
-
def Util.logger
|
68
|
-
@logger ||=
|
69
|
-
begin
|
70
|
-
l = Logger.new($stdout)
|
71
|
-
l.level = Logger::FATAL
|
72
|
-
l
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
##
|
77
|
-
# Construct a request packet.
|
78
|
-
#
|
79
|
-
# @param type_name command type's name (see COMMANDS)
|
80
|
-
# @param arg optional data to pack into the command
|
81
|
-
# @return packet (as a string)
|
82
|
-
def Util.pack_request(type_name, arg='')
|
83
|
-
type_num = NUMS[type_name.to_sym]
|
84
|
-
raise InvalidArgsError, "Invalid type name '#{type_name}'" unless type_num
|
85
|
-
arg = '' if not arg
|
86
|
-
"\0REQ" + [type_num, arg.size].pack('NN') + arg
|
87
|
-
end
|
88
|
-
|
89
|
-
##
|
90
|
-
# Return a Task based on the passed-in arguments.
|
91
|
-
#
|
92
|
-
# @param args either a single Task object or the arguments accepted by
|
93
|
-
# Task.new
|
94
|
-
# @return Task object
|
95
|
-
def Util.get_task_from_args(*args)
|
96
|
-
if (args[0].class == Task || args[0].class.superclass == Task)
|
97
|
-
return args[0]
|
98
|
-
elsif args.size <= 3
|
99
|
-
return Task.new(*args)
|
100
|
-
else
|
101
|
-
raise InvalidArgsError, 'Incorrect number of args to get_task_from_args'
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
##
|
106
|
-
# Read from a socket, giving up if it doesn't finish quickly enough.
|
107
|
-
# NetworkError is thrown if we don't read all the bytes in time.
|
108
|
-
#
|
109
|
-
# @param sock Socket from which we read
|
110
|
-
# @param len number of bytes to read
|
111
|
-
# @param timeout maximum number of seconds we'll take; nil for no timeout
|
112
|
-
# @return full data that was read
|
113
|
-
def Util.timed_recv(sock, len, timeout=nil)
|
114
|
-
data = ''
|
115
|
-
end_time = Time.now.to_f + timeout if timeout
|
116
|
-
while data.size < len and (not timeout or Time.now.to_f < end_time) do
|
117
|
-
IO::select([sock], nil, nil, timeout ? end_time - Time.now.to_f : nil) \
|
118
|
-
or break
|
119
|
-
begin
|
120
|
-
data += sock.readpartial(len - data.size)
|
121
|
-
rescue
|
122
|
-
raise NetworkError, "Unable to read data from socket."
|
123
|
-
end
|
124
|
-
end
|
125
|
-
if data.size < len
|
126
|
-
raise NetworkError, "Read #{data.size} byte(s) instead of #{len}"
|
127
|
-
end
|
128
|
-
data
|
129
|
-
end
|
130
|
-
|
131
|
-
##
|
132
|
-
# Read a response packet from a socket.
|
133
|
-
#
|
134
|
-
# @param sock Socket connected to a job server
|
135
|
-
# @param timeout timeout in seconds, nil for no timeout
|
136
|
-
# @return array consisting of integer packet type and data
|
137
|
-
def Util.read_response(sock, timeout=nil)
|
138
|
-
end_time = Time.now.to_f + timeout if timeout
|
139
|
-
head = timed_recv(sock, 12, timeout)
|
140
|
-
magic, type, len = head.unpack('a4NN')
|
141
|
-
raise ProtocolError, "Invalid magic '#{magic}'" unless magic == "\0RES"
|
142
|
-
buf = len > 0 ?
|
143
|
-
timed_recv(sock, len, timeout ? end_time - Time.now.to_f : nil) : ''
|
144
|
-
type = COMMANDS[type]
|
145
|
-
raise ProtocolError, "Invalid packet type #{type}" unless type
|
146
|
-
[type, buf]
|
147
|
-
end
|
148
|
-
|
149
|
-
##
|
150
|
-
# Send a request packet over a socket.
|
151
|
-
#
|
152
|
-
# @param sock Socket connected to a job server
|
153
|
-
# @param req request packet to send
|
154
|
-
def Util.send_request(sock, req)
|
155
|
-
len = with_safe_socket_op{ sock.write(req) }
|
156
|
-
if len != req.size
|
157
|
-
raise NetworkError, "Wrote #{len} instead of #{req.size}"
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
##
|
162
|
-
# Add default ports to a job server or list of servers.
|
163
|
-
#
|
164
|
-
# @param servers a server hostname or "host:port" or array of servers
|
165
|
-
# @return an array of "host:port" strings
|
166
|
-
def Util.normalize_job_servers(servers)
|
167
|
-
if servers.class == String or servers.class == Symbol
|
168
|
-
servers = [ servers.to_s ]
|
169
|
-
end
|
170
|
-
servers.map {|s| s =~ /:/ ? s : "#{s}:#{DEFAULT_PORT}" }
|
171
|
-
end
|
172
|
-
|
173
|
-
##
|
174
|
-
# Convert job server info and a handle into a string.
|
175
|
-
#
|
176
|
-
# @param hostport "host:port" of job server
|
177
|
-
# @param handle job server-returned handle for a task
|
178
|
-
# @return "host:port//handle"
|
179
|
-
def Util.handle_to_str(hostport, handle)
|
180
|
-
"#{hostport}//#{handle}"
|
181
|
-
end
|
182
|
-
|
183
|
-
##
|
184
|
-
# Reverse Util.handle_to_str.
|
185
|
-
#
|
186
|
-
# @param str "host:port//handle"
|
187
|
-
# @return [hostport, handle]
|
188
|
-
def Util.str_to_handle(str)
|
189
|
-
str =~ %r{^([^:]+:\d+)//(.+)}
|
190
|
-
return [$1, $2]
|
191
|
-
end
|
192
|
-
|
193
|
-
def self.with_safe_socket_op
|
194
|
-
begin
|
195
|
-
yield
|
196
|
-
rescue Exception => ex
|
197
|
-
raise ServerDownException.new(ex.message)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def Util.ability_name_with_prefix(prefix,name)
|
202
|
-
"#{prefix}\t#{name}"
|
203
|
-
end
|
204
|
-
|
205
|
-
class << self
|
206
|
-
alias :ability_name_for_perl :ability_name_with_prefix
|
207
|
-
end
|
208
|
-
|
209
|
-
end
|
210
|
-
|
211
|
-
end
|