perfectqueue 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +4 -0
- data/lib/perfectqueue/backend/rdb_compat.rb +98 -72
- data/lib/perfectqueue/version.rb +1 -1
- data/spec/rdb_compat_backend_spec.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7274d143afaecb7d6ee09cac6d4e287813dcf1bc
|
4
|
+
data.tar.gz: 25c4271e2bbcb2734c92234a73c59121e383834c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc0acb6de0b1771606a5a8047f48d6c6e904722af0416291951cb87cfca8a65bd16b501099a1540e0f55ab7f9a41c650321b6cc87add520ead66b69acf61def2
|
7
|
+
data.tar.gz: 1b85520494ad5059f0dc5dc187eeab5810a51bd707e6931b21e1663c0425b0fcf05921ebb424f7aa1102e744a3f1e317cda7d0fe55d3fd36e947f895ba0420e3
|
data/ChangeLog
CHANGED
@@ -78,55 +78,7 @@ module PerfectQueue
|
|
78
78
|
# connection test
|
79
79
|
}
|
80
80
|
|
81
|
-
|
82
|
-
# server's internal thread ID counter. It is unique while the MySQL
|
83
|
-
# server is running.
|
84
|
-
# https://bugs.mysql.com/bug.php?id=19806
|
85
|
-
#
|
86
|
-
# An acquired task is marked with next_timeout and CONNECTION_ID().
|
87
|
-
# Therefore while alive_time is not changed and we don't restart
|
88
|
-
# the server in 1 second, they won't conflict.
|
89
|
-
if config[:disable_resource_limit]
|
90
|
-
@update_sql = <<SQL
|
91
|
-
UPDATE `#{@table}`
|
92
|
-
JOIN (
|
93
|
-
SELECT id
|
94
|
-
FROM `#{@table}` FORCE INDEX (`index_#{@table}_on_timeout`)
|
95
|
-
WHERE #{EVENT_HORIZON} < timeout AND timeout <= :now
|
96
|
-
ORDER BY timeout ASC
|
97
|
-
LIMIT :max_acquire) AS t1 USING(id)
|
98
|
-
SET timeout=:next_timeout, owner=CONNECTION_ID()
|
99
|
-
SQL
|
100
|
-
@sql = <<SQL
|
101
|
-
SELECT id, timeout, data, created_at, resource
|
102
|
-
FROM `#{@table}`
|
103
|
-
WHERE timeout = ? AND owner = CONNECTION_ID()
|
104
|
-
SQL
|
105
|
-
else
|
106
|
-
@update_sql = <<SQL
|
107
|
-
UPDATE `#{@table}`
|
108
|
-
JOIN (
|
109
|
-
SELECT id, IFNULL(max_running, 1) / (IFNULL(running, 0) + 1) AS weight
|
110
|
-
FROM `#{@table}`
|
111
|
-
LEFT JOIN (
|
112
|
-
SELECT resource, COUNT(1) AS running
|
113
|
-
FROM `#{@table}` AS t1
|
114
|
-
WHERE timeout > :now AND resource IS NOT NULL
|
115
|
-
GROUP BY resource
|
116
|
-
) AS t2 USING(resource)
|
117
|
-
WHERE #{EVENT_HORIZON} < timeout AND timeout <= :now AND IFNULL(max_running - running, 1) > 0
|
118
|
-
ORDER BY weight DESC, timeout ASC
|
119
|
-
LIMIT :max_acquire
|
120
|
-
) AS t3 USING (id)
|
121
|
-
SET timeout = :next_timeout, owner = CONNECTION_ID()
|
122
|
-
SQL
|
123
|
-
@sql = <<SQL
|
124
|
-
SELECT id, timeout, data, created_at, resource, max_running
|
125
|
-
FROM `#{@table}`
|
126
|
-
WHERE timeout = ? AND owner = CONNECTION_ID()
|
127
|
-
SQL
|
128
|
-
end
|
129
|
-
|
81
|
+
@disable_resource_limit = config[:disable_resource_limit]
|
130
82
|
@cleanup_interval = config[:cleanup_interval] || DEFAULT_DELETE_INTERVAL
|
131
83
|
# If cleanup_interval > max_request_per_child / max_acquire,
|
132
84
|
# some processes won't run DELETE query.
|
@@ -240,7 +192,6 @@ SQL
|
|
240
192
|
def acquire(alive_time, max_acquire, options)
|
241
193
|
now = (options[:now] || Time.now).to_i
|
242
194
|
next_timeout = now + alive_time
|
243
|
-
tasks = nil
|
244
195
|
t0 = nil
|
245
196
|
|
246
197
|
if @cleanup_interval_count <= 0
|
@@ -252,27 +203,11 @@ SQL
|
|
252
203
|
}
|
253
204
|
end
|
254
205
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
end
|
261
|
-
@table_unlock.call
|
262
|
-
|
263
|
-
tasks = []
|
264
|
-
@db.fetch(@sql, next_timeout) {|row|
|
265
|
-
attributes = create_attributes(nil, row)
|
266
|
-
task_token = Token.new(row[:id])
|
267
|
-
task = AcquiredTask.new(@client, row[:id], attributes, task_token)
|
268
|
-
tasks.push task
|
269
|
-
}
|
270
|
-
@cleanup_interval_count -= 1
|
271
|
-
|
272
|
-
return tasks
|
273
|
-
}
|
274
|
-
ensure
|
275
|
-
STDERR.puts "PQ:acquire from #{@table}:%6f sec (%d tasks)" % [Process.clock_gettime(Process::CLOCK_MONOTONIC)-t0,tasks.size] if tasks
|
206
|
+
if @disable_resource_limit
|
207
|
+
return acquire_without_resource(next_timeout, now, max_acquire)
|
208
|
+
else
|
209
|
+
return acquire_with_resource(next_timeout, now, max_acquire)
|
210
|
+
end
|
276
211
|
end
|
277
212
|
|
278
213
|
def force_finish(key, retention_time, options)
|
@@ -454,7 +389,98 @@ SQL
|
|
454
389
|
}
|
455
390
|
end
|
456
391
|
|
392
|
+
def acquire_without_resource(next_timeout, now, max_acquire)
|
393
|
+
# MySQL's CONNECTION_ID() is a 64bit unsigned integer from the
|
394
|
+
# server's internal thread ID counter. It is unique while the MySQL
|
395
|
+
# server is running.
|
396
|
+
# https://bugs.mysql.com/bug.php?id=19806
|
397
|
+
#
|
398
|
+
# An acquired task is marked with next_timeout and CONNECTION_ID().
|
399
|
+
# Therefore while alive_time is not changed and we don't restart
|
400
|
+
# the server in 1 second, they won't conflict.
|
401
|
+
update_sql = <<SQL
|
402
|
+
UPDATE `#{@table}`
|
403
|
+
JOIN (
|
404
|
+
SELECT id
|
405
|
+
FROM `#{@table}` FORCE INDEX (`index_#{@table}_on_timeout`)
|
406
|
+
WHERE #{EVENT_HORIZON} < timeout AND timeout <= :now
|
407
|
+
ORDER BY timeout ASC
|
408
|
+
LIMIT :max_acquire) AS t1 USING(id)
|
409
|
+
SET timeout=:next_timeout, owner=CONNECTION_ID()
|
410
|
+
SQL
|
411
|
+
select_sql = <<SQL
|
412
|
+
SELECT id, timeout, data, created_at, resource
|
413
|
+
FROM `#{@table}`
|
414
|
+
WHERE timeout = ? AND owner = CONNECTION_ID()
|
415
|
+
SQL
|
416
|
+
t0 = 0
|
417
|
+
connect_locked do
|
418
|
+
t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
419
|
+
n = @db[update_sql, next_timeout: next_timeout, now: now, max_acquire: max_acquire].update
|
420
|
+
@table_unlock.call
|
421
|
+
STDERR.puts "PQ:acquire from #{@table}:%6f sec (%d tasks)" % [Process.clock_gettime(Process::CLOCK_MONOTONIC)-t0,n]
|
422
|
+
return nil if n <= 0
|
423
|
+
|
424
|
+
tasks = []
|
425
|
+
@db.fetch(select_sql, next_timeout) do |row|
|
426
|
+
attributes = create_attributes(nil, row)
|
427
|
+
task_token = Token.new(row[:id])
|
428
|
+
task = AcquiredTask.new(@client, row[:id], attributes, task_token)
|
429
|
+
tasks.push task
|
430
|
+
end
|
431
|
+
@cleanup_interval_count -= 1
|
432
|
+
return tasks
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
def acquire_with_resource(next_timeout, now, max_acquire)
|
437
|
+
t0 = nil
|
438
|
+
tasks = nil
|
439
|
+
sql = <<SQL
|
440
|
+
SELECT id, timeout, data, created_at, resource, max_running, IFNULL(max_running, 1) / (IFNULL(running, 0) + 1) AS weight
|
441
|
+
FROM `#{@table}`
|
442
|
+
LEFT JOIN (
|
443
|
+
SELECT resource AS res, COUNT(1) AS running
|
444
|
+
FROM `#{@table}` AS T
|
445
|
+
WHERE timeout > ? AND created_at IS NOT NULL AND resource IS NOT NULL
|
446
|
+
GROUP BY resource
|
447
|
+
) AS R ON resource = res
|
448
|
+
WHERE #{EVENT_HORIZON} < timeout AND timeout <= ?
|
449
|
+
AND created_at IS NOT NULL
|
450
|
+
AND (max_running-running IS NULL OR max_running-running > 0)
|
451
|
+
ORDER BY weight DESC, timeout ASC
|
452
|
+
LIMIT ?
|
453
|
+
SQL
|
454
|
+
connect_locked do
|
455
|
+
t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
456
|
+
tasks = []
|
457
|
+
@db.fetch(sql, now, now, max_acquire) do |row|
|
458
|
+
attributes = create_attributes(nil, row)
|
459
|
+
task_token = Token.new(row[:id])
|
460
|
+
task = AcquiredTask.new(@client, row[:id], attributes, task_token)
|
461
|
+
tasks.push task
|
462
|
+
end
|
463
|
+
return nil if tasks.empty?
|
464
|
+
|
465
|
+
sql = "UPDATE `#{@table}` FORCE INDEX (PRIMARY) SET timeout=? WHERE timeout <= ? AND id IN ("
|
466
|
+
params = [sql, next_timeout, now]
|
467
|
+
params.concat tasks.map(&:key)
|
468
|
+
sql << '?,' * tasks.size
|
469
|
+
sql.chop!
|
470
|
+
sql << ") AND created_at IS NOT NULL"
|
471
|
+
|
472
|
+
n = @db[*params].update
|
473
|
+
if n != tasks.size
|
474
|
+
# preempted
|
475
|
+
return nil
|
476
|
+
end
|
477
|
+
end
|
478
|
+
@cleanup_interval_count -= 1
|
479
|
+
return tasks
|
480
|
+
ensure
|
481
|
+
STDERR.puts "PQ:acquire from #{@table}:%6f sec (%d tasks)" % \
|
482
|
+
[Process.clock_gettime(Process::CLOCK_MONOTONIC)-t0, tasks.size] if tasks
|
483
|
+
end
|
457
484
|
end
|
458
485
|
end
|
459
486
|
end
|
460
|
-
|
data/lib/perfectqueue/version.rb
CHANGED
@@ -96,7 +96,7 @@ describe Backend::RDBCompatBackend do
|
|
96
96
|
end
|
97
97
|
it 'supports mysql' do
|
98
98
|
expect(Backend::RDBCompatBackend.new(client, config)).to be_an_instance_of(Backend::RDBCompatBackend)
|
99
|
-
expect(db.instance_variable_get(:@
|
99
|
+
expect(db.instance_variable_get(:@disable_resource_limit)).to be_falsey
|
100
100
|
end
|
101
101
|
it 'doesn\'t support postgres' do
|
102
102
|
config = {url: 'postgres://localhost', table: table}
|
@@ -110,7 +110,7 @@ describe Backend::RDBCompatBackend do
|
|
110
110
|
it 'disable_resource_limit' do
|
111
111
|
config = {url: 'mysql2://root:@localhost/perfectqueue_test', table: table, disable_resource_limit: true}
|
112
112
|
db = Backend::RDBCompatBackend.new(client, config)
|
113
|
-
expect(db.instance_variable_get(:@
|
113
|
+
expect(db.instance_variable_get(:@disable_resource_limit)).to be_truthy
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perfectqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|