perfectqueue 0.8.54 → 0.9.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.
@@ -8,7 +8,6 @@ op.banner += %[ <command>
8
8
  commands:
9
9
  list Show list of tasks
10
10
  submit <key> <type> <data> Submit a new task
11
- cancel_request <key> Cancel request
12
11
  force_finish <key> Force finish a task
13
12
  run <class> Run a worker process
14
13
  init Initialize a backend database
@@ -76,11 +75,6 @@ begin
76
75
  cmd = :list
77
76
  usage nil unless ARGV.length == 0
78
77
 
79
- when 'cancel_request' ,'cancel'
80
- cmd = :cancel
81
- usage nil unless ARGV.length == 1
82
- key = ARGV[0]
83
-
84
78
  when 'force_finish' ,'finish'
85
79
  cmd = :finish
86
80
  usage nil unless ARGV.length == 1
@@ -141,11 +135,6 @@ when :list
141
135
  }
142
136
  puts "#{n} entries."
143
137
 
144
- when :cancel
145
- PerfectQueue.open(config_load_proc.call) {|queue|
146
- queue[key].cancel_request!
147
- }
148
-
149
138
  when :finish
150
139
  PerfectQueue.open(config_load_proc.call) {|queue|
151
140
  queue[key].force_finish!
@@ -102,8 +102,8 @@ module PerfectQueue
102
102
  def send_signal(sig)
103
103
  begin
104
104
  Process.kill(sig, @pid)
105
- rescue Errno::ESRCH, Errno::EPERM => e
106
- @log.info "#{e.class}: #{e.message}\n#{e.backtrace}"
105
+ rescue Errno::ESRCH, Errno::EPERM
106
+ # TODO log?
107
107
  end
108
108
  end
109
109
 
@@ -121,7 +121,7 @@ module PerfectQueue
121
121
  end
122
122
 
123
123
  def process(task)
124
- @log.info "acquired task task=#{task.key} id=#{@processor_id}"
124
+ @log.info "acquired task task=#{task.key} id=#{@processor_id}: #{task.inspect}"
125
125
  begin
126
126
  r = @runner.new(task)
127
127
  @tm.set_task(task, r)
@@ -27,10 +27,6 @@ module PerfectQueue
27
27
 
28
28
  attr_reader :key
29
29
 
30
- def cancel_request!(options={})
31
- @client.cancel_request(@key, options)
32
- end
33
-
34
30
  def force_finish!(options={})
35
31
  @client.force_finish(@key, options)
36
32
  end
@@ -68,10 +68,6 @@ module PerfectQueue
68
68
  def running?
69
69
  status == TaskStatus::RUNNING
70
70
  end
71
-
72
- def cancel_requested?
73
- status == TaskStatus::CANCEL_REQUESTED
74
- end
75
71
  end
76
72
 
77
73
  class TaskMetadata
@@ -147,7 +147,7 @@ module PerfectQueue
147
147
  def task_heartbeat
148
148
  @task.heartbeat!
149
149
  rescue
150
- # finished, cancel_requested, preempted, etc.
150
+ # finished, preempted, etc.
151
151
  kill_task($!)
152
152
  end
153
153
  end
@@ -178,13 +178,6 @@ module PerfectQueue
178
178
  }
179
179
  end
180
180
 
181
- def cancel_request!(*args, &block)
182
- @log.info "cancel request task=#{self.key}" if @log
183
- @task_monitor.task_finished(self) {
184
- super(*args, &block)
185
- }
186
- end
187
-
188
181
  def update_data!(hash)
189
182
  @log.info "update data #{hash.inspect} task=#{self.key}" if @log
190
183
  @task_monitor.external_task_heartbeat(self) {
@@ -21,7 +21,6 @@ module PerfectQueue
21
21
  WAITING = :waiting
22
22
  RUNNING = :running
23
23
  FINISHED = :finished
24
- CANCEL_REQUESTED = :cancel_requested
25
24
  end
26
25
  end
27
26
 
@@ -1,3 +1,3 @@
1
1
  module PerfectQueue
2
- VERSION = "0.8.54"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -28,7 +28,6 @@ module PerfectQueue
28
28
  config = block.call
29
29
 
30
30
  @config = config
31
- @log = config[:logger] || Logger.new(STDERR)
32
31
  @runner = runner
33
32
 
34
33
  @detach_wait = config[:detach_wait] || config['detach_wait'] || 10.0
@@ -67,11 +66,9 @@ module PerfectQueue
67
66
 
68
67
  else
69
68
  # child process finished unexpectedly
70
- @log.info "Child process finished unexpectedly pid=#{pid}"
71
69
  end
72
70
 
73
- rescue Errno::ECHILD => e
74
- @log.info "#{e.class}: #{e.message}\n#{e.backtrace}"
71
+ rescue Errno::ECHILD
75
72
  end
76
73
  end
77
74
 
@@ -133,3 +130,4 @@ module PerfectQueue
133
130
  end
134
131
 
135
132
  end
133
+
data/spec/queue_spec.rb CHANGED
@@ -20,8 +20,6 @@ describe Queue do
20
20
  queue.submit('task01', 'type1', {}, :now=>now+1)
21
21
  }.to raise_error AlreadyExistsError
22
22
 
23
- queue['task01'].cancel_request!(:now=>now+2)
24
-
25
23
  expect {
26
24
  allow(STDERR).to receive(:puts)
27
25
  queue.submit('task01', 'type1', {}, :now=>now+10)
@@ -161,7 +159,6 @@ describe Queue do
161
159
  #queue['task01'].metadata.finished?.should == false
162
160
  #queue['task01'].metadata.running?.should == false
163
161
  #queue['task01'].metadata.waiting?.should == true
164
- #queue['task01'].metadata.cancel_requested?.should == false
165
162
 
166
163
  task01 = queue.poll(:now=>now+10, :alive_time=>10)
167
164
  expect(task01.key).to eq('task01')
@@ -169,37 +166,12 @@ describe Queue do
169
166
  expect(queue['task01'].metadata.finished?).to eq(false)
170
167
  expect(queue['task01'].metadata.running?).to eq(true)
171
168
  expect(queue['task01'].metadata.waiting?).to eq(false)
172
- expect(queue['task01'].metadata.cancel_requested?).to eq(false)
173
-
174
- task01.cancel_request!
175
-
176
- # status of cancel_requested running tasks is cancel_requested
177
- expect(queue['task01'].metadata.finished?).to eq(false)
178
- expect(queue['task01'].metadata.running?).to eq(false)
179
- expect(queue['task01'].metadata.waiting?).to eq(false)
180
- expect(queue['task01'].metadata.cancel_requested?).to eq(true)
181
169
 
182
170
  task01.finish!
183
171
 
184
172
  expect(queue['task01'].metadata.finished?).to eq(true)
185
173
  expect(queue['task01'].metadata.running?).to eq(false)
186
174
  expect(queue['task01'].metadata.waiting?).to eq(false)
187
- expect(queue['task01'].metadata.cancel_requested?).to eq(false)
188
- end
189
-
190
- it 'fail canceling finished task' do
191
- now = Time.now.to_i
192
- queue.submit('task01', 'type1', {"a"=>1}, :now=>now+0)
193
-
194
- task01 = queue.poll(:now=>now+10, :alive_time=>10)
195
- expect(task01.key).to eq('task01')
196
-
197
- task01.finish!
198
-
199
- expect {
200
- allow(STDERR).to receive(:puts)
201
- queue['task01'].cancel_request!
202
- }.to raise_error AlreadyFinishedError
203
175
  end
204
176
 
205
177
  it 'retention_time' do
@@ -21,11 +21,15 @@ describe Backend::RDBBackend do
21
21
 
22
22
  context '#submit' do
23
23
  it 'adds task' do
24
- db.submit('key', '{"foo":"bar"}')
24
+ expect(db.submit('key', '{"foo":"bar"}')).to be true
25
25
  row = db.db.fetch("SELECT * FROM `#{table}` WHERE id=? LIMIT 1", 'key').first
26
26
  expect(row[:created_at]).not_to be_nil
27
27
  expect(row[:data]).to eq('{"foo":"bar"}')
28
28
  end
29
+ it 'returns nil for a duplicated task' do
30
+ expect(db.submit('key', '{"foo":"bar"}')).to be true
31
+ expect(db.submit('key', '{"foo":"bar"}')).to be_nil
32
+ end
29
33
  end
30
34
 
31
35
  context '#cancel' do
@@ -55,7 +59,7 @@ describe Backend::RDBBackend do
55
59
  end
56
60
  context 'error' do
57
61
  it 'returns block result' do
58
- expect(RuntimeError).to receive(:new).exactly(db.max_retry_count).and_call_original
62
+ expect(RuntimeError).to receive(:new).exactly(Backend::RDBBackend::MAX_RETRY).and_call_original
59
63
  allow(STDERR).to receive(:puts)
60
64
  allow(db).to receive(:sleep)
61
65
  expect do
@@ -65,19 +69,5 @@ describe Backend::RDBBackend do
65
69
  end.to raise_error(RuntimeError)
66
70
  end
67
71
  end
68
- context 'cannot connect' do
69
- let (:uri){ 'mysql2://root:@nonexistent/perfectqueue_test' }
70
- let (:db) do
71
- Backend::RDBBackend.new(uri, table)
72
- end
73
- it 'raises Sequel::DatabaseConnectionError' do
74
- allow(STDERR).to receive(:puts)
75
- slept = 0
76
- expect(db).to receive(:sleep).exactly(9).times{|n| slept += n }
77
- expect(db.db).to receive(:connect).exactly(10).times.and_call_original
78
- expect{ db.__send__(:connect){ db.db.run('SELECT 1;') } }.to raise_error(Sequel::DatabaseConnectionError)
79
- expect(slept).to be < 30
80
- end
81
- end
82
72
  end
83
73
  end
@@ -166,11 +166,15 @@ describe Backend::RDBCompatBackend do
166
166
  end
167
167
 
168
168
  context '#submit' do
169
- it 'adds task' do
170
- db.submit('key', 'test', nil, {})
169
+ it 'returns true' do
170
+ expect(db.submit('key', 'test', nil, {})).to be_an_instance_of(Task)
171
+ end
172
+ it 'returns true (gzip)' do
173
+ expect(db.submit('key', 'test', nil, {compression: 'gzip'})).to be_an_instance_of(Task)
171
174
  end
172
- it 'gzip' do
173
- db.submit('key', 'test', nil, {compression: 'gzip'})
175
+ it 'returns nil if duplication' do
176
+ expect(db.submit('key', 'test', nil, {})).to be_an_instance_of(Task)
177
+ expect{db.submit('key', 'test', nil, {})}.to raise_error(IdempotentAlreadyExistsError)
174
178
  end
175
179
  end
176
180
 
@@ -195,85 +199,52 @@ describe Backend::RDBCompatBackend do
195
199
  expect(ary[0]).to be_an_instance_of(AcquiredTask)
196
200
  end
197
201
  end
198
- context 'some tasks' do
199
- let :t0 do now - 100 end
200
- before do
201
- db.submit('key1', 'test1', nil, {now: t0})
202
- db.submit('key2', 'test2', nil, {now: t0})
203
- db.submit('key3', 'test3', nil, {now: t0})
202
+ context 'disable_resource_limit' do
203
+ let (:config) do
204
+ {url: 'mysql2://root:@localhost/perfectqueue_test', table: table, disable_resource_limit: true}
204
205
  end
205
- it 'returns 3 tasks' do
206
- now0 = Time.at(t0)
207
- expect(now0).to receive(:to_time).exactly(3).times.and_call_original
208
- db.list({}) do |task|
209
- expect(task.timeout).to eq now0.to_time
210
- end
211
- ary = db.acquire(alive_time, max_acquire, {now: now})
212
- expect(ary).to be_an_instance_of(Array)
213
- expect(ary.size).to eq(3)
214
- expect(ary[0]).to be_an_instance_of(AcquiredTask)
215
- expect(ary[1]).to be_an_instance_of(AcquiredTask)
216
- expect(ary[2]).to be_an_instance_of(AcquiredTask)
217
-
218
- now1 = Time.at(now + alive_time)
219
- expect(now1).to receive(:to_time).exactly(3).times.and_call_original
220
- db.list({}){|task| expect(task.timeout).to eq now1.to_time }
206
+ before do
207
+ db.submit(key, 'test', nil, {})
221
208
  end
222
- it 'returns 2 tasks' do
223
- db.instance_variable_set(:@prefetch_break_types, 'test2')
209
+ it 'returns a task' do
224
210
  ary = db.acquire(alive_time, max_acquire, {})
225
211
  expect(ary).to be_an_instance_of(Array)
226
- expect(ary.size).to eq(2)
212
+ expect(ary.size).to eq(1)
227
213
  expect(ary[0]).to be_an_instance_of(AcquiredTask)
228
- expect(ary[1]).to be_an_instance_of(AcquiredTask)
229
214
  end
230
215
  end
231
- context 'stole a task' do
232
- let :t0 do now - 100 end
216
+ context 'some tasks' do
217
+ let :t0 do now - 300 end
218
+ let :t1 do now - 200 end
219
+ let :t2 do now - 100 end
233
220
  before do
234
221
  db.submit('key1', 'test1', nil, {now: t0})
235
222
  db.submit('key2', 'test2', nil, {now: t0})
236
- db.submit('key3', 'test3', nil, {now: t0})
237
- end
238
- it 'returns nil' do
239
- # hook and steal a task
240
- mock = double('prefetch_break_types')
241
- db.instance_variable_set(:@prefetch_break_types, mock)
242
- allow(mock).to receive(:include?) do
243
- db.db['UPDATE `test_queues` SET timeout=? WHERE id=?', now+300, 'key2'].update
244
- false
245
- end
223
+ db.submit('key3', 'test3', nil, {now: t1})
224
+ db.submit('key4', 'test4', nil, {now: t2})
225
+ db.submit('key5', 'test5', nil, {now: t2})
226
+ end
227
+ it 'returns 5 tasks' do
228
+ ary = []
229
+ db.list({}){|task| ary << task }
230
+ expect(ary[0].timeout.to_i).to eq t0
231
+ expect(ary[1].timeout.to_i).to eq t0
232
+ expect(ary[2].timeout.to_i).to eq t1
233
+ expect(ary[3].timeout.to_i).to eq t2
234
+ expect(ary[4].timeout.to_i).to eq t2
246
235
 
247
- ary = db.acquire(alive_time, max_acquire, {})
248
- expect(ary).to be_nil
249
- end
250
- end
251
- end
236
+ ary = db.acquire(alive_time, max_acquire, {now: now})
237
+ expect(ary).to be_an_instance_of(Array)
238
+ expect(ary.size).to eq(5)
239
+ expect(ary[0]).to be_an_instance_of(AcquiredTask)
240
+ expect(ary[1]).to be_an_instance_of(AcquiredTask)
241
+ expect(ary[2]).to be_an_instance_of(AcquiredTask)
242
+ expect(ary[3]).to be_an_instance_of(AcquiredTask)
243
+ expect(ary[4]).to be_an_instance_of(AcquiredTask)
252
244
 
253
- context '#cancel_request' do
254
- let (:key){ 'key' }
255
- let (:task_token){ Backend::RDBCompatBackend::Token.new(key) }
256
- let (:retention_time) { 42 }
257
- let (:delete_timeout){ now + retention_time }
258
- let (:options){ {now: now} }
259
- context 'have a task' do
260
- before do
261
- db.submit(key, 'test', nil, {})
262
- end
263
- it 'returns nil' do
264
- expect(db.cancel_request(key, options)).to be_nil
265
- row = db.db.fetch("SELECT created_at FROM `#{table}` WHERE id=? LIMIT 1", key).first
266
- expect(row[:created_at]).to eq 0
267
- end
268
- end
269
- context 'already finished' do
270
- before do
271
- expect(STDERR).to receive(:puts)
272
- db.submit(key, 'test', nil, {})
273
- db.finish(task_token, retention_time, options)
274
- end
275
- it 'raises AlreadyFinishedError' do
276
- expect{db.cancel_request(key, options)}.to raise_error(AlreadyFinishedError)
245
+ now1 = Time.at(now + alive_time)
246
+ expect(now1).to receive(:to_time).exactly(5).times.and_call_original
247
+ db.list({}){|task| expect(task.timeout).to eq now1.to_time }
277
248
  end
278
249
  end
279
250
  end
@@ -348,15 +319,6 @@ describe Backend::RDBCompatBackend do
348
319
  expect{db.heartbeat(task_token, 0, {})}.to raise_error(PreemptedError)
349
320
  end
350
321
  end
351
- context 'canceled task' do
352
- before do
353
- db.submit(key, 'test', nil, {})
354
- db.cancel_request(key, options)
355
- end
356
- it 'returns nil' do
357
- expect( db.heartbeat(task_token, 0, {}) ).to be_nil
358
- end
359
- end
360
322
  end
361
323
 
362
324
  context '#connect' do
@@ -367,7 +329,7 @@ describe Backend::RDBCompatBackend do
367
329
  end
368
330
  context 'error' do
369
331
  it 'returns block result' do
370
- expect(RuntimeError).to receive(:new).exactly(db.max_retry_count).and_call_original
332
+ expect(RuntimeError).to receive(:new).exactly(Backend::RDBCompatBackend::MAX_RETRY).and_call_original
371
333
  allow(STDERR).to receive(:puts)
372
334
  allow(db).to receive(:sleep)
373
335
  expect do
@@ -376,18 +338,6 @@ describe Backend::RDBCompatBackend do
376
338
  end
377
339
  end.to raise_error(RuntimeError)
378
340
  end
379
- context 'cannot connect' do
380
- let (:config){ {url: 'mysql2://root:@nonexistent/perfectqueue_test', table: table} }
381
- it 'raises Sequel::DatabaseConnectionError' do
382
- allow(STDERR).to receive(:puts)
383
- d = Backend::RDBCompatBackend.new(client, config)
384
- slept = 0
385
- expect(d).to receive(:sleep).exactly(9).times{|n| slept += n }
386
- expect(d.db).to receive(:connect).exactly(10).times.and_call_original
387
- expect{ d.__send__(:connect){ d.db.run('SELECT 1;') } }.to raise_error(Sequel::DatabaseConnectionError)
388
- expect(slept).to eq(18)
389
- end
390
- end
391
341
  end
392
342
  end
393
343
 
@@ -541,13 +491,6 @@ describe Backend::RDBCompatBackend do
541
491
  end
542
492
  end
543
493
  end
544
- context 'created_at is 0' do
545
- it 'status is :cancel_requested' do
546
- data[:created_at] = 0
547
- r = db.__send__(:create_attributes, now, row)
548
- expect(r[:status]).to eq TaskStatus::CANCEL_REQUESTED
549
- end
550
- end
551
494
  context 'created_at > 0' do
552
495
  context 'timeout' do
553
496
  it 'status is :waiting' do
data/spec/spec_helper.rb CHANGED
@@ -1,16 +1,15 @@
1
1
  $LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
2
2
 
3
- require 'perfectqueue'
4
-
5
3
  if ENV['SIMPLE_COV']
6
4
  require 'simplecov'
7
5
  SimpleCov.start do
8
- add_filter 'spec/'
9
6
  add_filter 'pkg/'
10
7
  add_filter 'vendor/'
11
8
  end
12
9
  end
13
10
 
11
+ require 'perfectqueue'
12
+
14
13
  if ENV["CI"]
15
14
  require 'coveralls'
16
15
  Coveralls.wear!