background_queue 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rspec +1 -0
- data/.rvmrc +48 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +20 -0
- data/README.md +69 -0
- data/Rakefile +42 -0
- data/TODO +2 -0
- data/VERSION +1 -0
- data/background_queue.gemspec +158 -0
- data/bin/bg_queue +26 -0
- data/lib/background_queue.rb +8 -0
- data/lib/background_queue/client.rb +96 -0
- data/lib/background_queue/client_lib/command.rb +36 -0
- data/lib/background_queue/client_lib/config.rb +109 -0
- data/lib/background_queue/client_lib/connection.rb +105 -0
- data/lib/background_queue/client_lib/job_handle.rb +19 -0
- data/lib/background_queue/command.rb +49 -0
- data/lib/background_queue/config.rb +118 -0
- data/lib/background_queue/server_lib/balanced_queue.rb +108 -0
- data/lib/background_queue/server_lib/config.rb +339 -0
- data/lib/background_queue/server_lib/event_connection.rb +133 -0
- data/lib/background_queue/server_lib/event_server.rb +35 -0
- data/lib/background_queue/server_lib/job.rb +252 -0
- data/lib/background_queue/server_lib/job_registry.rb +30 -0
- data/lib/background_queue/server_lib/lru.rb +193 -0
- data/lib/background_queue/server_lib/owner.rb +54 -0
- data/lib/background_queue/server_lib/priority_queue.rb +156 -0
- data/lib/background_queue/server_lib/queue_registry.rb +123 -0
- data/lib/background_queue/server_lib/server.rb +314 -0
- data/lib/background_queue/server_lib/sorted_workers.rb +52 -0
- data/lib/background_queue/server_lib/task.rb +79 -0
- data/lib/background_queue/server_lib/task_registry.rb +51 -0
- data/lib/background_queue/server_lib/thread_manager.rb +121 -0
- data/lib/background_queue/server_lib/worker.rb +18 -0
- data/lib/background_queue/server_lib/worker_balancer.rb +97 -0
- data/lib/background_queue/server_lib/worker_client.rb +94 -0
- data/lib/background_queue/server_lib/worker_thread.rb +70 -0
- data/lib/background_queue/utils.rb +40 -0
- data/lib/background_queue/worker/base.rb +46 -0
- data/lib/background_queue/worker/calling.rb +59 -0
- data/lib/background_queue/worker/config.rb +35 -0
- data/lib/background_queue/worker/environment.rb +70 -0
- data/lib/background_queue/worker/worker_loader.rb +94 -0
- data/lib/background_queue_server.rb +21 -0
- data/lib/background_queue_worker.rb +5 -0
- data/spec/background_queue/client_lib/command_spec.rb +75 -0
- data/spec/background_queue/client_lib/config_spec.rb +156 -0
- data/spec/background_queue/client_lib/connection_spec.rb +170 -0
- data/spec/background_queue/client_spec.rb +95 -0
- data/spec/background_queue/command_spec.rb +34 -0
- data/spec/background_queue/config_spec.rb +134 -0
- data/spec/background_queue/server_lib/balanced_queue_spec.rb +122 -0
- data/spec/background_queue/server_lib/config_spec.rb +443 -0
- data/spec/background_queue/server_lib/event_connection_spec.rb +190 -0
- data/spec/background_queue/server_lib/event_server_spec.rb +48 -0
- data/spec/background_queue/server_lib/integration/full_test_spec.rb +247 -0
- data/spec/background_queue/server_lib/integration/queue_integration_spec.rb +98 -0
- data/spec/background_queue/server_lib/integration/serialize_spec.rb +127 -0
- data/spec/background_queue/server_lib/job_registry_spec.rb +65 -0
- data/spec/background_queue/server_lib/job_spec.rb +525 -0
- data/spec/background_queue/server_lib/owner_spec.rb +33 -0
- data/spec/background_queue/server_lib/priority_queue_spec.rb +182 -0
- data/spec/background_queue/server_lib/server_spec.rb +353 -0
- data/spec/background_queue/server_lib/sorted_workers_spec.rb +122 -0
- data/spec/background_queue/server_lib/task_registry_spec.rb +69 -0
- data/spec/background_queue/server_lib/task_spec.rb +20 -0
- data/spec/background_queue/server_lib/thread_manager_spec.rb +106 -0
- data/spec/background_queue/server_lib/worker_balancer_spec.rb +127 -0
- data/spec/background_queue/server_lib/worker_client_spec.rb +196 -0
- data/spec/background_queue/server_lib/worker_thread_spec.rb +125 -0
- data/spec/background_queue/utils_spec.rb +27 -0
- data/spec/background_queue/worker/base_spec.rb +35 -0
- data/spec/background_queue/worker/calling_spec.rb +103 -0
- data/spec/background_queue/worker/environment_spec.rb +67 -0
- data/spec/background_queue/worker/worker_loader_spec.rb +103 -0
- data/spec/background_queue_spec.rb +7 -0
- data/spec/resources/config-client.yml +7 -0
- data/spec/resources/config-serialize.yml +12 -0
- data/spec/resources/config.yml +12 -0
- data/spec/resources/example_worker.rb +4 -0
- data/spec/resources/example_worker_with_error.rb +4 -0
- data/spec/resources/test_worker.rb +8 -0
- data/spec/shared/queue_registry_shared.rb +216 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/default_task.rb +9 -0
- data/spec/support/private.rb +23 -0
- data/spec/support/simple_server.rb +28 -0
- data/spec/support/simple_task.rb +58 -0
- data/spec/support/test_worker_server.rb +205 -0
- metadata +254 -0
@@ -0,0 +1,339 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'ipaddress'
|
3
|
+
|
4
|
+
module BackgroundQueue::ServerLib
|
5
|
+
|
6
|
+
#The server configuration which is stored as a YAML file containing a root key for each environments configuration, much like database.yml.
|
7
|
+
#
|
8
|
+
#Example
|
9
|
+
#=======
|
10
|
+
#
|
11
|
+
# development:
|
12
|
+
# address:
|
13
|
+
# host: 127.0.0.1
|
14
|
+
# port: 3000
|
15
|
+
# workers:
|
16
|
+
# - http://127.0.0.1:801/background_queue
|
17
|
+
# secret: this_is_used_to_make_sure_it_is_secure
|
18
|
+
# task_file: /path/to/file/to/save/running/tasks
|
19
|
+
# production:
|
20
|
+
# address:
|
21
|
+
# host: 0.0.0.0
|
22
|
+
# port: 3000
|
23
|
+
# connections_per_worker: 10
|
24
|
+
# workers:
|
25
|
+
# - http://192.168.3.1:801/background_queue
|
26
|
+
# - http://192.168.3.2:801/background_queue
|
27
|
+
# secret: this_is_used_to_make_sure_it_is_secure
|
28
|
+
# system_task_options:
|
29
|
+
# domain: the_default_domain
|
30
|
+
# jobs
|
31
|
+
# - cron: "0 22 * * 1-5"
|
32
|
+
# worker: some_worker
|
33
|
+
# args:
|
34
|
+
# arg1: 22
|
35
|
+
# arg2: "hello"
|
36
|
+
class Config < BackgroundQueue::Config
|
37
|
+
|
38
|
+
#the list of workers that are called using http
|
39
|
+
attr_reader :workers
|
40
|
+
|
41
|
+
|
42
|
+
#the shared secret to make sure the worker is not called directly from the internet
|
43
|
+
attr_reader :secret
|
44
|
+
|
45
|
+
#a path where tasks are saved when the server shuts down, and loaded when it starts back up. This will store tasks being lost when restarting the server.
|
46
|
+
attr_reader :task_file
|
47
|
+
|
48
|
+
#an array of scheduled jobs
|
49
|
+
attr_reader :jobs
|
50
|
+
|
51
|
+
#the address to listen on
|
52
|
+
attr_reader :address
|
53
|
+
|
54
|
+
#the number of connections allowed for each active worker
|
55
|
+
attr_reader :connections_per_worker
|
56
|
+
|
57
|
+
#used for polling task and jobs. Should include a domain entry if your worker uses domain lookups
|
58
|
+
attr_reader :system_task_options
|
59
|
+
|
60
|
+
#load the configration using a hash just containing the environment
|
61
|
+
def self.load_hash(env_config, path)
|
62
|
+
BackgroundQueue::ServerLib::Config.new(
|
63
|
+
build_worker_entries(env_config, path),
|
64
|
+
get_secret_entry(env_config, path),
|
65
|
+
get_address_entry(env_config, path),
|
66
|
+
get_connections_per_worker_entry(env_config, path),
|
67
|
+
get_jobs_entry(env_config, path),
|
68
|
+
get_system_task_options_entry(env_config, path),
|
69
|
+
get_task_file_entry(env_config, path)
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
class << self
|
74
|
+
private
|
75
|
+
|
76
|
+
def build_worker_entries(env_config, path)
|
77
|
+
entries = []
|
78
|
+
workers_entry = BackgroundQueue::Utils.get_hash_entry(env_config, :workers)
|
79
|
+
if workers_entry && workers_entry.kind_of?(Array)
|
80
|
+
workers_entry.each_with_index do |entry, index|
|
81
|
+
begin
|
82
|
+
entries << BackgroundQueue::ServerLib::Config::Worker.new(entry)
|
83
|
+
rescue Exception=>e
|
84
|
+
raise BackgroundQueue::LoadError, "Error loading 'worker' entry (#{index + 1}) from background queue server configuration file #{full_path(path)}: #{e.message}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
elsif workers_entry
|
88
|
+
raise BackgroundQueue::LoadError, "Error loading 'workers' entries configuration file #{full_path(path)}: invalid data type (#{workers_entry.class.name}), expecting Array"
|
89
|
+
else
|
90
|
+
raise BackgroundQueue::LoadError, "Missing 'workers' in background queue server configuration file #{full_path(path)}"
|
91
|
+
end
|
92
|
+
entries
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_secret_entry(env_config, path)
|
96
|
+
secret_entry = BackgroundQueue::Utils.get_hash_entry(env_config, :secret)
|
97
|
+
if secret_entry && secret_entry.kind_of?(String)
|
98
|
+
secret_entry.strip!
|
99
|
+
if secret_entry.length < 20
|
100
|
+
raise BackgroundQueue::LoadError, "Error loading 'secret' entry in background queue server configuration file #{full_path(path)}: length too short (must be at least 20 characters long)"
|
101
|
+
end
|
102
|
+
secret_entry
|
103
|
+
elsif secret_entry
|
104
|
+
raise BackgroundQueue::LoadError, "Error loading 'secret' entry in background queue server configuration file #{full_path(path)}: invalid data type (#{secret_entry.class.name}), expecting String"
|
105
|
+
else
|
106
|
+
raise BackgroundQueue::LoadError, "Missing 'secret' entry in background queue server configuration file #{full_path(path)}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_address_entry(env_config, path)
|
111
|
+
begin
|
112
|
+
BackgroundQueue::ServerLib::Config::Address.new(BackgroundQueue::Utils.get_hash_entry(env_config, :address))
|
113
|
+
rescue Exception=>e
|
114
|
+
raise BackgroundQueue::LoadError, "Error loading 'address' entry in background queue server configuration file #{full_path(path)}: #{e.message}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def get_connections_per_worker_entry(env_config, path)
|
119
|
+
connections_per_worker_entry = BackgroundQueue::Utils.get_hash_entry(env_config, :connections_per_worker)
|
120
|
+
if connections_per_worker_entry && connections_per_worker_entry.kind_of?(Integer)
|
121
|
+
connections_per_worker_entry
|
122
|
+
elsif connections_per_worker_entry
|
123
|
+
raise BackgroundQueue::LoadError, "Error loading 'connections_per_worker' entry in background queue server configuration file #{full_path(path)}: invalid data type (#{connections_per_worker_entry.class.name}), expecting Integer"
|
124
|
+
else
|
125
|
+
raise BackgroundQueue::LoadError, "Missing 'connections_per_worker' entry in background queue server configuration file #{full_path(path)}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_system_task_options_entry(env_config, path)
|
130
|
+
opts_entry = BackgroundQueue::Utils.get_hash_entry(env_config, :system_task_options)
|
131
|
+
return {} if opts_entry.nil?
|
132
|
+
if opts_entry.kind_of?(Hash)
|
133
|
+
opts_entry
|
134
|
+
else
|
135
|
+
raise BackgroundQueue::LoadError, "Error loading 'system_task_options' entry in background queue server configuration file #{full_path(path)}: invalid data type (#{opts_entry.class.name}), expecting Hash (of options)"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_jobs_entry(env_config, path)
|
140
|
+
jobs_entry = BackgroundQueue::Utils.get_hash_entry(env_config, :jobs)
|
141
|
+
return [] if jobs_entry.nil?
|
142
|
+
if jobs_entry.kind_of?(Array)
|
143
|
+
retval = []
|
144
|
+
for job in jobs_entry
|
145
|
+
begin
|
146
|
+
retval << BackgroundQueue::ServerLib::Config::Job.new(job)
|
147
|
+
rescue Exception=>e
|
148
|
+
raise BackgroundQueue::LoadError, "Error loading 'jobs' entry in background queue server configuration file #{full_path(path)}: #{e.message}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
retval
|
152
|
+
else
|
153
|
+
raise BackgroundQueue::LoadError, "Error loading 'jobs' entry in background queue server configuration file #{full_path(path)}: invalid data type (#{jobs_entry.class.name}), expecting Array (of jobs)"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def get_task_file_entry(env_config, path)
|
158
|
+
task_file = BackgroundQueue::Utils.get_hash_entry(env_config, :task_file)
|
159
|
+
if task_file && task_file.kind_of?(String)
|
160
|
+
task_file.strip!
|
161
|
+
#make sure the file exists of the directory is writable
|
162
|
+
if !File.exist?(task_file)
|
163
|
+
dir = File.dirname(task_file)
|
164
|
+
if !File.exist?(dir)
|
165
|
+
#check if we can create the directory
|
166
|
+
begin
|
167
|
+
FileUtils.mkdir_p dir
|
168
|
+
rescue Exception=>e
|
169
|
+
raise BackgroundQueue::LoadError, "Error loading 'task_file' entry in background queue server configuration file #{full_path(path)}: unable to create directory #{dir} (#{e.message})"
|
170
|
+
end
|
171
|
+
else
|
172
|
+
#check if we can write in the directory
|
173
|
+
begin
|
174
|
+
FileUtils.touch task_file
|
175
|
+
rescue Exception=>e
|
176
|
+
raise BackgroundQueue::LoadError, "Error loading 'task_file' entry in background queue server configuration file #{full_path(path)}: unable to write to file #{task_file} (#{e.message})"
|
177
|
+
end
|
178
|
+
FileUtils.rm task_file
|
179
|
+
end
|
180
|
+
end
|
181
|
+
task_file
|
182
|
+
elsif task_file
|
183
|
+
raise BackgroundQueue::LoadError, "Error loading 'task_file' entry in background queue server configuration file #{full_path(path)}: Invalid data type (#{task_file.class.name}), expecting String"
|
184
|
+
else
|
185
|
+
nil
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
#do not call this directly, use a load_* method
|
192
|
+
def initialize(workers, secret, address, connections_per_worker, jobs, system_task_options, task_file)
|
193
|
+
@workers = workers
|
194
|
+
@secret = secret
|
195
|
+
@address = address
|
196
|
+
@connections_per_worker = connections_per_worker
|
197
|
+
@jobs = jobs
|
198
|
+
@system_task_options = system_task_options
|
199
|
+
@task_file = task_file
|
200
|
+
end
|
201
|
+
|
202
|
+
class Address
|
203
|
+
attr_reader :host
|
204
|
+
attr_reader :port
|
205
|
+
|
206
|
+
|
207
|
+
def initialize(config_entry)
|
208
|
+
if config_entry.nil?
|
209
|
+
@host = "0.0.0.0"
|
210
|
+
@port = BackgroundQueue::Config::DEFAULT_PORT
|
211
|
+
else
|
212
|
+
port = BackgroundQueue::Utils.get_hash_entry(config_entry, :port)
|
213
|
+
if port.nil?
|
214
|
+
@port = BackgroundQueue::Config::DEFAULT_PORT
|
215
|
+
elsif port.kind_of?(Numeric)
|
216
|
+
@port = port.to_i
|
217
|
+
elsif port.kind_of?(String)
|
218
|
+
if port.to_s.strip == port.to_s.to_i.to_s
|
219
|
+
@port = port.to_i
|
220
|
+
else
|
221
|
+
raise "Invalid port: #{port}"
|
222
|
+
end
|
223
|
+
else
|
224
|
+
raise "Invalid port: should be number or string"
|
225
|
+
end
|
226
|
+
if @port <= 0
|
227
|
+
raise "Invalid port: must be greater then zero"
|
228
|
+
end
|
229
|
+
host = BackgroundQueue::Utils.get_hash_entry(config_entry, :host)
|
230
|
+
if host.nil?
|
231
|
+
@host = "0.0.0.0"
|
232
|
+
elsif host.kind_of?(String)
|
233
|
+
if IPAddress.valid? host
|
234
|
+
@host = host
|
235
|
+
else
|
236
|
+
raise "Invalid host: #{host}"
|
237
|
+
end
|
238
|
+
else
|
239
|
+
raise "Invalid host: should be string"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
#A server entry in the configuration
|
247
|
+
class Worker
|
248
|
+
|
249
|
+
attr_reader :uri
|
250
|
+
|
251
|
+
def initialize(config_entry)
|
252
|
+
if config_entry.nil?
|
253
|
+
raise BackgroundQueue::LoadError, "Missing worker url"
|
254
|
+
elsif config_entry.kind_of?(String)
|
255
|
+
raise BackgroundQueue::LoadError, "Missing worker url" if config_entry.strip.length == 0
|
256
|
+
begin
|
257
|
+
@uri = URI.parse(config_entry)
|
258
|
+
rescue URI::InvalidURIError
|
259
|
+
raise BackgroundQueue::LoadError, "Invalid worker url (#{config_entry})"
|
260
|
+
end
|
261
|
+
else
|
262
|
+
raise BackgroundQueue::LoadError, "Invalid data type (#{config_entry.class.name}), expecting String (as a url)"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def url
|
267
|
+
@uri.to_s
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
class Job
|
272
|
+
|
273
|
+
|
274
|
+
attr_accessor :at
|
275
|
+
attr_accessor :in
|
276
|
+
attr_accessor :cron
|
277
|
+
attr_accessor :every
|
278
|
+
attr_accessor :type
|
279
|
+
attr_accessor :args
|
280
|
+
|
281
|
+
def initialize(job_entry)
|
282
|
+
raise "Empty Job Entry" if job_entry.nil?
|
283
|
+
@at = BackgroundQueue::Utils.get_hash_entry(job_entry, :at)
|
284
|
+
@in = BackgroundQueue::Utils.get_hash_entry(job_entry, :in)
|
285
|
+
@cron = BackgroundQueue::Utils.get_hash_entry(job_entry, :cron)
|
286
|
+
@every = BackgroundQueue::Utils.get_hash_entry(job_entry, :every)
|
287
|
+
if !@at.nil?
|
288
|
+
@type = :at
|
289
|
+
elsif !@in.nil?
|
290
|
+
@type = :in
|
291
|
+
elsif !@cron.nil?
|
292
|
+
@type=:cron
|
293
|
+
elsif !@every.nil?
|
294
|
+
@type=:every
|
295
|
+
else
|
296
|
+
raise "Job is missing timer designation (at, in or cron)"
|
297
|
+
end
|
298
|
+
@worker = BackgroundQueue::Utils.get_hash_entry(job_entry, :worker)
|
299
|
+
raise "Job is missing worker entry" if @worker.nil?
|
300
|
+
|
301
|
+
@args = {}
|
302
|
+
args_entry = BackgroundQueue::Utils.get_hash_entry(job_entry, :args)
|
303
|
+
unless args_entry.nil?
|
304
|
+
raise "Invalid 'args' entry in job: expecting Hash of arguments, got #{args_entry.class.name}" unless args_entry.kind_of?(Hash)
|
305
|
+
@args = args_entry
|
306
|
+
end
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
def schedule(scheduler, server)
|
311
|
+
case @type
|
312
|
+
when :at
|
313
|
+
scheduler.at @at do
|
314
|
+
run(server)
|
315
|
+
end
|
316
|
+
when :in
|
317
|
+
scheduler.in @in do
|
318
|
+
run(server)
|
319
|
+
end
|
320
|
+
when :cron
|
321
|
+
scheduler.cron @cron do
|
322
|
+
run(server)
|
323
|
+
end
|
324
|
+
when :every
|
325
|
+
scheduler.every @every do
|
326
|
+
run(server)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def run(server)
|
332
|
+
task = BackgroundQueue::ServerLib::Task.new(:system, :scheduled, self.object_id, 2, @worker, @args, server.config.system_task_options)
|
333
|
+
server.task_queue.add_task(task)
|
334
|
+
end
|
335
|
+
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
|
3
|
+
module BackgroundQueue::ServerLib
|
4
|
+
class EventConnection < EventMachine::Connection
|
5
|
+
|
6
|
+
attr_accessor :server
|
7
|
+
|
8
|
+
STAGE_LENGTH = 0
|
9
|
+
STAGE_BODY = 1
|
10
|
+
|
11
|
+
MAX_BODY_LENGTH = 9999999
|
12
|
+
|
13
|
+
|
14
|
+
def post_init
|
15
|
+
@data = ""
|
16
|
+
@length = 0
|
17
|
+
@stage = STAGE_LENGTH
|
18
|
+
end
|
19
|
+
|
20
|
+
def receive_data(data)
|
21
|
+
@data << data
|
22
|
+
if @stage == STAGE_LENGTH
|
23
|
+
if @data.length >= 6
|
24
|
+
s_header = @data.slice!(0,6)
|
25
|
+
version, length = s_header.unpack("SL")
|
26
|
+
|
27
|
+
if version == 1
|
28
|
+
@length = length
|
29
|
+
@stage = STAGE_BODY
|
30
|
+
if length > MAX_BODY_LENGTH || length <= 0
|
31
|
+
raise "Invalid length: #{length}"
|
32
|
+
end
|
33
|
+
else
|
34
|
+
raise "Invalid header version: #{version}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if @stage == STAGE_BODY && @data.length == @length
|
40
|
+
#body received
|
41
|
+
process_data(@data)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def process_data(data)
|
46
|
+
begin
|
47
|
+
cmd = BackgroundQueue::Command.from_buf(data)
|
48
|
+
result = process_command(cmd)
|
49
|
+
send_result(result)
|
50
|
+
rescue Exception=>e
|
51
|
+
@server.logger.error("Error processing command: #{e.message}")
|
52
|
+
send_error(e.message)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def send_result(command)
|
57
|
+
send(command.to_buf)
|
58
|
+
end
|
59
|
+
|
60
|
+
def send_error(message)
|
61
|
+
send_result(build_simple_command(:error, message))
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_simple_command(type, message)
|
65
|
+
BackgroundQueue::Command.new(type, {}, {:message=>message})
|
66
|
+
end
|
67
|
+
|
68
|
+
def send(data)
|
69
|
+
data_with_header = [1, data.length, data].pack("SLZ#{data.length}")
|
70
|
+
send_data(data_with_header)
|
71
|
+
end
|
72
|
+
|
73
|
+
def process_command(command)
|
74
|
+
case command.code.to_s
|
75
|
+
when 'add_task'
|
76
|
+
process_add_task_command(command)
|
77
|
+
when 'add_tasks'
|
78
|
+
process_add_tasks_command(command)
|
79
|
+
when 'remove_tasks'
|
80
|
+
process_remove_tasks_command(command)
|
81
|
+
when 'get_status'
|
82
|
+
process_get_status_command(command)
|
83
|
+
when 'stats'
|
84
|
+
process_stats_command(command)
|
85
|
+
else
|
86
|
+
raise "Unknown command: #{command.code.inspect}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def process_add_task_command(command)
|
91
|
+
@server.logger.debug("add_task: #{command.args[:owner_id]}, #{command.args[:job_id]}, #{command.args[:task_id]}")
|
92
|
+
task = BackgroundQueue::ServerLib::Task.new(command.args[:owner_id], command.args[:job_id], command.args[:task_id], command.args[:priority], command.args[:worker], command.args[:params], command.options)
|
93
|
+
server.task_queue.add_task(task)
|
94
|
+
@server.change_stat(:tasks, 1)
|
95
|
+
build_simple_command(:result, "ok")
|
96
|
+
end
|
97
|
+
|
98
|
+
def process_add_tasks_command(command)
|
99
|
+
@server.logger.debug("add_tasks: #{command.args[:owner_id]}, #{command.args[:job_id]}, #{command.args[:tasks].inspect}")
|
100
|
+
shared_params = command.args[:shared_parameters]
|
101
|
+
shared_params = {} if shared_params.nil?
|
102
|
+
owner_id = command.args[:owner_id]
|
103
|
+
job_id = command.args[:job_id]
|
104
|
+
priority = command.args[:priority]
|
105
|
+
worker = command.args[:worker]
|
106
|
+
for task_data in command.args[:tasks]
|
107
|
+
if task_data[1].nil?
|
108
|
+
merged_params = shared_params
|
109
|
+
else
|
110
|
+
merged_params = shared_params.clone.update(task_data[1])
|
111
|
+
end
|
112
|
+
task = BackgroundQueue::ServerLib::Task.new(owner_id, job_id, task_data[0], priority, worker, merged_params, command.options)
|
113
|
+
server.task_queue.add_task(task)
|
114
|
+
end
|
115
|
+
@server.change_stat(:tasks, command.args[:tasks].length)
|
116
|
+
build_simple_command(:result, "ok")
|
117
|
+
end
|
118
|
+
|
119
|
+
def process_get_status_command(command)
|
120
|
+
job = @server.jobs.get_job(command.args[:job_id])
|
121
|
+
if job.nil?
|
122
|
+
build_simple_command(:job_not_found, "job #{command.args[:job_id]} not found")
|
123
|
+
else
|
124
|
+
BackgroundQueue::Command.new(:status, {}, job.get_current_progress)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def process_stats_command(command)
|
129
|
+
BackgroundQueue::Command.new(:stats, {}, @server.get_stats)
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|