perfectqueue 0.7.32 → 0.8.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.
Files changed (52) hide show
  1. data/.gitignore +6 -0
  2. data/ChangeLog +0 -62
  3. data/Gemfile +3 -0
  4. data/README.md +239 -0
  5. data/Rakefile +19 -0
  6. data/lib/perfectqueue.rb +68 -4
  7. data/lib/perfectqueue/application.rb +30 -0
  8. data/lib/perfectqueue/application/base.rb +27 -0
  9. data/lib/perfectqueue/application/dispatch.rb +73 -0
  10. data/lib/perfectqueue/application/router.rb +69 -0
  11. data/lib/perfectqueue/backend.rb +44 -47
  12. data/lib/perfectqueue/backend/rdb_compat.rb +298 -0
  13. data/lib/perfectqueue/blocking_flag.rb +84 -0
  14. data/lib/perfectqueue/client.rb +117 -0
  15. data/lib/perfectqueue/command/perfectqueue.rb +108 -323
  16. data/lib/perfectqueue/daemons_logger.rb +80 -0
  17. data/lib/perfectqueue/engine.rb +85 -123
  18. data/lib/perfectqueue/error.rb +53 -0
  19. data/lib/perfectqueue/model.rb +37 -0
  20. data/lib/perfectqueue/multiprocess.rb +31 -0
  21. data/lib/perfectqueue/multiprocess/child_process.rb +108 -0
  22. data/lib/perfectqueue/multiprocess/child_process_monitor.rb +109 -0
  23. data/lib/perfectqueue/multiprocess/fork_processor.rb +164 -0
  24. data/lib/perfectqueue/multiprocess/thread_processor.rb +123 -0
  25. data/lib/perfectqueue/queue.rb +58 -0
  26. data/lib/perfectqueue/runner.rb +39 -0
  27. data/lib/perfectqueue/signal_queue.rb +112 -0
  28. data/lib/perfectqueue/task.rb +103 -0
  29. data/lib/perfectqueue/task_metadata.rb +98 -0
  30. data/lib/perfectqueue/task_monitor.rb +189 -0
  31. data/lib/perfectqueue/task_status.rb +27 -0
  32. data/lib/perfectqueue/version.rb +1 -3
  33. data/lib/perfectqueue/worker.rb +114 -196
  34. data/perfectqueue.gemspec +24 -0
  35. data/spec/queue_spec.rb +234 -0
  36. data/spec/spec_helper.rb +44 -0
  37. data/spec/worker_spec.rb +81 -0
  38. metadata +93 -40
  39. checksums.yaml +0 -7
  40. data/README.rdoc +0 -224
  41. data/lib/perfectqueue/backend/null.rb +0 -33
  42. data/lib/perfectqueue/backend/rdb.rb +0 -181
  43. data/lib/perfectqueue/backend/simpledb.rb +0 -139
  44. data/test/backend_test.rb +0 -259
  45. data/test/cat.sh +0 -2
  46. data/test/echo.sh +0 -4
  47. data/test/exec_test.rb +0 -61
  48. data/test/fail.sh +0 -2
  49. data/test/huge.sh +0 -2
  50. data/test/stress.rb +0 -99
  51. data/test/success.sh +0 -2
  52. data/test/test_helper.rb +0 -19
@@ -0,0 +1,84 @@
1
+ #
2
+ # PerfectQueue
3
+ #
4
+ # Copyright (C) 2012 FURUHASHI Sadayuki
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module PerfectQueue
20
+
21
+ class BlockingFlag
22
+ def initialize
23
+ require 'thread'
24
+ @set = false
25
+ @mutex = Mutex.new
26
+ @cond = ConditionVariable.new
27
+ end
28
+
29
+ def set!
30
+ toggled = false
31
+ @mutex.synchronize do
32
+ unless @set
33
+ @set = true
34
+ toggled = true
35
+ end
36
+ @cond.broadcast
37
+ end
38
+ return toggled
39
+ end
40
+
41
+ def reset!
42
+ toggled = false
43
+ @mutex.synchronize do
44
+ if @set
45
+ @set = false
46
+ toggled = true
47
+ end
48
+ @cond.broadcast
49
+ end
50
+ return toggled
51
+ end
52
+
53
+ def set?
54
+ @set
55
+ end
56
+
57
+ def set_region(&block)
58
+ set!
59
+ begin
60
+ block.call
61
+ ensure
62
+ reset!
63
+ end
64
+ end
65
+
66
+ def reset_region(&block)
67
+ reset!
68
+ begin
69
+ block.call
70
+ ensure
71
+ set!
72
+ end
73
+ end
74
+
75
+ def wait(timeout=nil)
76
+ @mutex.synchronize do
77
+ @cond.wait(@mutex, timeout)
78
+ end
79
+ self
80
+ end
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,117 @@
1
+ #
2
+ # PerfectQueue
3
+ #
4
+ # Copyright (C) 2012 FURUHASHI Sadayuki
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module PerfectQueue
20
+ class Client
21
+ def initialize(config)
22
+ @config = {}
23
+ config.each_pair {|k,v| @config[k.to_sym] = v }
24
+
25
+ @backend = Backend.new_backend(self, @config)
26
+
27
+ @max_acquire = @config[:max_acquire] || 1
28
+ @retention_time = @config[:retention_time] || 300
29
+ @alive_time = @config[:alive_time] || 300
30
+ @retry_wait = @config[:retry_wait] || 300 # TODO retry wait algorithm
31
+ end
32
+
33
+ attr_reader :backend
34
+ attr_reader :config
35
+
36
+ def init_database(options={})
37
+ @backend.init_database(options)
38
+ end
39
+
40
+ def get_task_metadata(key, options={})
41
+ @backend.get_task_metadata(key, options)
42
+ end
43
+
44
+ # :message => nil
45
+ # :alive_time => @alive_time
46
+ def preempt(key, options={})
47
+ alive_time = options[:alive_time] || @alive_time
48
+
49
+ @backend.preempt(key, alive_time, options)
50
+ end
51
+
52
+ def list(options={}, &block)
53
+ @backend.list(options, &block)
54
+ end
55
+
56
+ # :run_at => Time.now
57
+ # :message => nil
58
+ # :user => nil
59
+ # :priority => nil
60
+ def submit(key, type, data, options={})
61
+ @backend.submit(key, type, data, options)
62
+ end
63
+
64
+ # :max_acquire => nil
65
+ # :alive_time => nil
66
+ def acquire(options={})
67
+ alive_time = options[:alive_time] || @alive_time
68
+ max_acquire = options[:max_acquire] || @max_acquire
69
+
70
+ @backend.acquire(alive_time, max_acquire, options)
71
+ end
72
+
73
+ # :message => nil
74
+ def cancel_request(key, options={})
75
+ @backend.cancel_request(key, options)
76
+ end
77
+
78
+ def force_finish(key, options={})
79
+ retention_time = options[:retention_time] || @retention_time
80
+
81
+ @backend.force_finish(key, retention_time, options)
82
+ end
83
+
84
+ # :message => nil
85
+ # :retention_time => default_retention_time
86
+ def finish(task_token, options={})
87
+ retention_time = options[:retention_time] || @retention_time
88
+
89
+ @backend.finish(task_token, retention_time, options)
90
+ end
91
+
92
+ # :message => nil
93
+ # :alive_time => nil
94
+ def heartbeat(task_token, options={})
95
+ alive_time = options[:alive_time] || @alive_time
96
+
97
+ @backend.heartbeat(task_token, alive_time, options)
98
+ end
99
+
100
+ def release(task_token, options={})
101
+ alive_time = options[:alive_time] || 0
102
+
103
+ @backend.heartbeat(task_token, alive_time, options)
104
+ end
105
+
106
+ def retry(task_token, options={})
107
+ alive_time = options[:retry_wait] || @retry_wait
108
+
109
+ @backend.heartbeat(task_token, alive_time, options)
110
+ end
111
+
112
+ def close
113
+ @backend.close
114
+ end
115
+ end
116
+ end
117
+
@@ -3,380 +3,165 @@ require 'perfectqueue/version'
3
3
 
4
4
  op = OptionParser.new
5
5
 
6
- op.banner += " [-- <ARGV-for-exec-or-run>]"
7
- op.version = PerfectQueue::VERSION
8
-
9
- type = nil
10
- id = nil
11
- data = nil
12
- confout = nil
13
-
14
- defaults = {
15
- :timeout => 600,
16
- :poll_interval => 1,
17
- :kill_interval => 60,
18
- :workers => 1,
19
- :expire => 345600,
20
- }
21
-
22
- conf = { }
23
-
24
-
25
- op.on('-o', '--log PATH', "log file path") {|s|
26
- conf[:log] = s
27
- }
28
-
29
- op.on('-v', '--verbose', "verbose mode", TrueClass) {|b|
30
- conf[:verbose] = true
31
- }
32
- op.separator("")
33
-
34
- op.on('--push <ID> <DATA>', 'Push a task to the queue') {|s|
35
- type = :push
36
- id = s
37
- }
38
-
39
- op.on('--list', 'Show queued tasks', TrueClass) {|b|
40
- type = :list
41
- }
42
-
43
- op.on('--cancel <ID>', 'Cancel a queued task') {|s|
44
- type = :cancel
45
- id = s
46
- }
6
+ op.banner += %[ <command>
47
7
 
48
- op.on('--configure <PATH.yaml>', 'Write configuration file') {|s|
49
- type = :conf
50
- confout = s
51
- }
52
-
53
- op.separator("")
54
-
55
- op.on('--exec <COMMAND>', 'Execute command') {|s|
56
- type = :exec
57
- conf[:exec] = s
58
- }
59
-
60
- op.on('--run <SCRIPT.rb>', 'Run method named \'run\' defined in the script') {|s|
61
- type = :run
62
- conf[:run] = s
63
- }
64
-
65
- op.separator("")
66
-
67
- op.on('-f', '--file <PATH.yaml>', 'Read configuration file') {|s|
68
- (conf[:files] ||= []) << s
69
- }
70
-
71
- op.on('-C', '--run-class', 'Class name for --run (default: ::Run)') {|s|
72
- conf[:run_class] = s
73
- }
74
-
75
- op.on('-t', '--timeout <SEC>', 'Time for another worker to take over a task when this worker goes down (default: 600)', Integer) {|i|
76
- conf[:timeout] = i
77
- }
78
-
79
- op.on('-b', '--heartbeat-interval <SEC>', 'Threshold time to extend the timeout (heartbeat interval) (default: timeout * 3/4)', Integer) {|i|
80
- conf[:heartbeat_interval] = i
81
- }
8
+ commands:
9
+ list Show list of tasks
10
+ submit <key> <type> <data> Submit a new task
11
+ cancel_request <key> Cancel request
12
+ force_finish <key> Force finish a task
13
+ run <class> Run a worker process
14
+ init Initialize a backend database
82
15
 
83
- op.on('-x', '--kill-timeout <SEC>', 'Threshold time to kill a task process (default: timeout * 10)', Integer) {|i|
84
- conf[:kill_timeout] = i
85
- }
16
+ ]
17
+ op.version = PerfectQueue::VERSION
86
18
 
87
- op.on('-X', '--kill-interval <SEC>', 'Threshold time to retry killing a task process (default: 60)', Integer) {|i|
88
- conf[:kill_interval] = i
89
- }
19
+ env = ENV['RAILS_ENV'] || 'development'
20
+ config_path = 'config/perfectqueue.yml'
21
+ include_dirs = []
22
+ require_files = []
90
23
 
91
- op.on('-i', '--poll-interval <SEC>', 'Polling interval (default: 1)', Integer) {|i|
92
- conf[:poll_interval] = i
24
+ task_options = {
93
25
  }
94
26
 
95
- op.on('-r', '--retry-wait <SEC>', 'Time to retry a task when it is failed (default: same as timeout)', Integer) {|i|
96
- conf[:retry_wait] = i
97
- }
27
+ op.separator("options:")
98
28
 
99
- op.on('-D', '--delete-wait <SEC>', 'Time to delete a finished task when it succeeded (default: 3600)', Integer) {|i|
100
- conf[:delete_wait] = i
29
+ op.on('-e', '--environment ENV', 'Framework environment (default: development)') {|s|
30
+ env = s
101
31
  }
102
32
 
103
- op.on('-e', '--expire <SEC>', 'Threshold time to expire a task (default: 345601 (4days))', Integer) {|i|
104
- conf[:expire] = i
33
+ op.on('-c', '--config PATH.yml', 'Path to a configuration file (default: config/perfectqueue.yml)') {|s|
34
+ config_path = s
105
35
  }
106
36
 
107
- op.separator("")
37
+ op.separator("\noptions for submit:")
108
38
 
109
- op.on('--database <URI>', 'Use RDBMS for the backend database (e.g.: mysql://user:password@localhost/mydb)') {|s|
110
- conf[:backend_database] = s
39
+ op.on('-u', '--user USER', 'Set user') {|s|
40
+ task_options[:user] = s
111
41
  }
112
42
 
113
- op.on('--table <NAME>', 'backend: name of the table (default: perfectqueue)') {|s|
114
- conf[:backend_table] = s
43
+ op.on('-t', '--time UNIXTIME', 'Set time to run the task', Integer) {|i|
44
+ task_options[:run_at] = i
115
45
  }
116
46
 
117
- op.on('--simpledb <DOMAIN>', 'Use Amazon SimpleDB for the backend database (e.g.: --simpledb mydomain -k KEY_ID -s SEC_KEY)') {|s|
118
- conf[:backend_simpledb] = s
119
- }
120
-
121
- op.on('-k', '--key-id <ID>', 'AWS Access Key ID') {|s|
122
- conf[:backend_key_id] = s
123
- }
124
47
 
125
- op.on('-s', '--secret-key <KEY>', 'AWS Secret Access Key') {|s|
126
- conf[:backend_secret_key] = s
127
- }
128
-
129
- op.separator("")
130
-
131
- op.on('-w', '--worker <NUM>', 'Number of worker threads (default: 1)', Integer) {|i|
132
- conf[:workers] = i
133
- }
134
-
135
- op.on('-d', '--daemon <PIDFILE>', 'Daemonize (default: foreground)') {|s|
136
- conf[:daemon] = s
137
- }
138
-
139
- op.on('--env K=V', 'Set environment variable') {|s|
140
- k, v = s.split('=',2)
141
- (conf[:env] ||= {})[k] = v
142
- }
48
+ op.separator("\noptions for run:")
143
49
 
144
- op.on('-o', '--log <PATH>', "log file path") {|s|
145
- conf[:log] = s
50
+ op.on('-I', '--include PATH', 'Add $LOAD_PATH directory') {|s|
51
+ include_dirs << s
146
52
  }
147
53
 
148
- op.on('-v', '--verbose', "verbose mode", TrueClass) {|b|
149
- conf[:verbose] = true
54
+ op.on('-r', '--require PATH', 'Require files before starting') {|s|
55
+ require_files << s
150
56
  }
151
57
 
152
-
153
58
  (class<<self;self;end).module_eval do
154
59
  define_method(:usage) do |msg|
155
60
  puts op.to_s
156
- puts "error: #{msg}" if msg
61
+ puts "\nerror: #{msg}" if msg
157
62
  exit 1
158
63
  end
159
64
  end
160
65
 
161
-
162
66
  begin
163
- if eqeq = ARGV.index('--')
164
- argv = ARGV.slice!(0, eqeq)
165
- ARGV.slice!(0)
166
- else
167
- argv = ARGV.slice!(0..-1)
168
- end
169
- op.parse!(argv)
170
-
171
- case type
172
- when :push
173
- if argv.length != 1
174
- usage nil
175
- end
176
- data = argv[0]
177
-
178
- else
179
- if argv.length != 0
180
- usage nil
181
- end
182
- end
183
-
184
- if conf[:files]
185
- require 'yaml'
186
- docs = ''
187
- conf[:files].each {|file|
188
- docs << File.read(file)
189
- }
190
- y = {}
191
- YAML.load_documents(docs) {|yaml|
192
- yaml.each_pair {|k,v| y[k.to_sym] = v }
193
- }
67
+ op.parse!(ARGV)
68
+
69
+ usage nil if ARGV.empty?
70
+
71
+ cmd = ARGV.shift
72
+ case cmd
73
+ when 'list'
74
+ cmd = :list
75
+ usage nil unless ARGV.length == 0
76
+
77
+ when 'cancel_request' ,'cancel'
78
+ cmd = :cancel
79
+ usage nil unless ARGV.length == 1
80
+ key = ARGV[0]
81
+
82
+ when 'force_finish' ,'finish'
83
+ cmd = :finish
84
+ usage nil unless ARGV.length == 1
85
+ key = ARGV[0]
86
+
87
+ when 'submit'
88
+ cmd = :submit
89
+ usage nil unless ARGV.length == 3
90
+ key, type, data = *ARGV
91
+ require 'json'
92
+ data = JSON.load(data)
93
+
94
+ when 'run'
95
+ cmd = :run
96
+ usage nil unless ARGV.length == 1
97
+ klass = ARGV[0]
98
+
99
+ when 'init'
100
+ cmd = :init
101
+ usage nil unless ARGV.length == 0
194
102
 
195
- conf = defaults.merge(y).merge(conf)
196
-
197
- if ARGV.empty? && conf[:args]
198
- ARGV.clear
199
- ARGV.concat conf[:args]
200
- end
201
103
  else
202
- conf = defaults.merge(conf)
203
- end
204
-
205
- unless type
206
- if conf[:run]
207
- type = :run
208
- elsif conf[:exec]
209
- type = :exec
210
- else
211
- raise "--list, --push, --cancel, --configure, --exec or --run is required"
212
- end
213
- end
214
-
215
- unless conf[:heartbeat_interval]
216
- conf[:heartbeat_interval] = conf[:timeout] * 3/4
217
- end
218
-
219
- unless conf[:kill_timeout]
220
- conf[:kill_timeout] = conf[:timeout] * 10
221
- end
222
-
223
- unless conf[:retry_wait]
224
- conf[:retry_wait] = conf[:timeout]
225
- end
226
-
227
- if conf[:timeout] < conf[:heartbeat_interval]
228
- raise "--heartbeat-interval(=#{conf[:heartbeat_interval]}) must be larger than --timeout(=#{conf[:timeout]})"
229
- end
230
-
231
- if conf[:backend_database]
232
- conf[:backend_table] ||= 'perfectqueue'
233
- backend_proc = Proc.new {
234
- PerfectQueue::RDBBackend.new(conf[:backend_database], conf[:backend_table])
235
- }
236
- elsif conf[:backend_simpledb]
237
- conf[:backend_key_id] ||= ENV['AWS_ACCESS_KEY_ID']
238
- conf[:backend_secret_key] ||= ENV['AWS_SECRET_ACCESS_KEY']
239
- backend_proc = Proc.new {
240
- PerfectQueue::SimpleDBBackend.new(conf[:backend_key_id], conf[:backend_secret_key], conf[:backend_simpledb])
241
- }
242
-
243
- else
244
- raise "--database or --simpledb is required"
104
+ raise "unknown command: '#{cmd}'"
245
105
  end
246
106
 
247
107
  rescue
248
108
  usage $!.to_s
249
109
  end
250
110
 
251
-
252
- if confout
253
- require 'yaml'
254
-
255
- conf.delete(:files)
256
- conf[:args] = ARGV
257
-
258
- y = {}
259
- conf.each_pair {|k,v| y[k.to_s] = v }
260
-
261
- File.open(confout, "w") {|f|
262
- f.write y.to_yaml
263
- }
264
- exit 0
265
- end
266
-
267
-
268
- require 'logger'
111
+ require 'yaml'
269
112
  require 'perfectqueue'
270
- require 'perfectqueue/backend/rdb'
271
- require 'perfectqueue/backend/simpledb'
272
113
 
273
- backend = backend_proc.call
114
+ config_load_proc = Proc.new {
115
+ yaml = YAML.load(File.read(config_path))
116
+ conf = yaml[env]
117
+ unless conf
118
+ raise "Configuration file #{config_path} doesn't include configuration for environment '#{env}'"
119
+ end
120
+ conf
121
+ }
274
122
 
275
- case type
123
+
124
+ case cmd
276
125
  when :list
277
- format = "%26s %26s %26s %26s %s"
278
- puts format % ["id", "created_at", "timeout", "resource", "data"]
279
- time_format = "%Y-%m-%d %H:%M:%S %z"
280
126
  n = 0
281
- backend.list {|id,created_at,data,timeout,resource|
282
- puts format % [id, Time.at(created_at).strftime(time_format), Time.at(timeout).strftime(time_format), resource, data]
283
- n += 1
127
+ PerfectQueue.open(config_load_proc.call) {|queue|
128
+ format = "%30s %15s %18s %18s %28s %28s %s"
129
+ puts format % ["key", "type", "user", "status", "created_at", "timeout", "data"]
130
+ queue.each {|task|
131
+ puts format % [task.key, task.type, task.user, task.status, task.created_at, task.timeout, task.data]
132
+ n += 1
133
+ }
284
134
  }
285
135
  puts "#{n} entries."
286
136
 
287
137
  when :cancel
288
- canceled = backend.cancel(id)
289
- if canceled
290
- puts "Task id=#{id} is canceled."
291
- else
292
- puts "Task id=#{id} does not exist. abort"
293
- end
294
-
295
- when :push
296
- submitted = backend.submit(id, data, Time.now.to_i)
297
- if submitted
298
- puts "Task id=#{id} is submitted."
299
- else
300
- puts "Task id=#{id} is duplicated. abort."
301
- end
302
-
303
- when :exec, :run
304
- if conf[:daemon]
305
- exit!(0) if fork
306
- Process.setsid
307
- exit!(0) if fork
308
- File.umask(0)
309
- STDIN.reopen("/dev/null")
310
- STDOUT.reopen("/dev/null", "w")
311
- STDERR.reopen("/dev/null", "w")
312
- File.open(conf[:daemon], "w") {|f|
313
- f.write Process.pid.to_s
314
- }
315
- end
316
-
317
- (conf[:env] || {}).each_pair {|k,v|
318
- ENV[k] = v
138
+ PerfectQueue.open(config_load_proc.call) {|queue|
139
+ queue[key].cancel_request!
319
140
  }
320
141
 
321
- if type == :run
322
- load File.expand_path(conf[:run])
323
- run_class = eval(conf[:run_class] || 'Run')
324
- else
325
- require 'shellwords'
326
- cmd = conf[:exec]
327
- Run = Class.new(PerfectQueue::ExecRunner) do
328
- define_method(:initialize) {|task|
329
- super(cmd, task)
330
- }
331
- end
332
- run_class = Run
333
- end
334
-
335
- conf[:run_class] = run_class
336
-
337
- if log_file = conf[:log]
338
- log_out = File.open(conf[:log], "a")
339
- else
340
- log_out = STDOUT
341
- end
342
- log_out.sync = true
343
-
344
- log = Logger.new(log_out)
345
- if conf[:verbose]
346
- log.level = Logger::DEBUG
347
- else
348
- log.level = Logger::INFO
349
- end
350
-
351
- engine = PerfectQueue::Engine.new(backend, log, conf)
352
-
353
- trap :INT do
354
- log.info "shutting down..."
355
- engine.stop
356
- end
357
-
358
- trap :TERM do
359
- log.info "shutting down..."
360
- engine.stop
361
- end
142
+ when :finish
143
+ PerfectQueue.open(config_load_proc.call) {|queue|
144
+ queue[key].force_finish!
145
+ }
362
146
 
363
- trap :HUP do
364
- if log_file
365
- log_out.reopen(log_file, "a")
366
- end
367
- end
147
+ when :submit
148
+ PerfectQueue.open(config_load_proc.call) {|queue|
149
+ queue.submit(key, type, data, task_options)
150
+ }
368
151
 
369
- log.info "PerfectQueue-#{PerfectQueue::VERSION}"
152
+ when :run
153
+ include_dirs.each {|path|
154
+ $LOAD_PATH << File.expand_path(path)
155
+ }
156
+ require_files.each {|file|
157
+ require file
158
+ }
159
+ klass = Object.const_get(klass)
160
+ PerfectQueue::Worker.run(klass, &config_load_proc)
370
161
 
371
- begin
372
- engine.run
373
- engine.shutdown
374
- rescue
375
- log.error $!.to_s
376
- $!.backtrace.each {|x|
377
- log.error " #{x}"
378
- }
379
- exit 1
380
- end
162
+ when :init
163
+ PerfectQueue.open(config_load_proc.call) {|queue|
164
+ queue.client.init_database
165
+ }
381
166
  end
382
167