perfectqueue 0.8.17 → 0.8.18
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/ChangeLog +8 -0
- data/lib/perfectqueue/backend/rdb_compat.rb +68 -39
- data/lib/perfectqueue/version.rb +1 -1
- data/spec/spec_helper.rb +3 -1
- metadata +2 -2
data/ChangeLog
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
|
2
|
+
== 2012-09-04 version 0.8.18
|
3
|
+
|
4
|
+
* rdb_compat backend uses table lock to avoid dead locks with InnoDB
|
5
|
+
* rdb_compat backend uses bulk cleanup to improve throughput
|
6
|
+
* rdb_compat backend uses created_at in WHERE clause to work with partitioning
|
7
|
+
* rdb_compat backend supports disable_resource_limit to improve acquire() performance
|
8
|
+
|
9
|
+
|
2
10
|
== 2012-09-03 version 0.8.17
|
3
11
|
|
4
12
|
* Increased wait time before starting processors to 1 second at average and
|
@@ -43,7 +43,16 @@ module PerfectQueue
|
|
43
43
|
# connection test
|
44
44
|
}
|
45
45
|
|
46
|
-
|
46
|
+
if config[:disable_resource_limit]
|
47
|
+
@sql = <<SQL
|
48
|
+
SELECT id, timeout, data, created_at, resource
|
49
|
+
FROM `#{@table}`
|
50
|
+
WHERE timeout <= ? AND timeout <= ? AND created_at IS NOT NULL
|
51
|
+
ORDER BY timeout ASC
|
52
|
+
LIMIT ?
|
53
|
+
SQL
|
54
|
+
else
|
55
|
+
@sql = <<SQL
|
47
56
|
SELECT id, timeout, data, created_at, resource, max_running, max_running/running AS weight
|
48
57
|
FROM `#{@table}`
|
49
58
|
LEFT JOIN (
|
@@ -52,24 +61,37 @@ LEFT JOIN (
|
|
52
61
|
WHERE timeout > ? AND created_at IS NOT NULL AND resource IS NOT NULL
|
53
62
|
GROUP BY resource
|
54
63
|
) AS R ON resource = res
|
55
|
-
WHERE timeout <= ? AND (max_running-running IS NULL OR max_running-running > 0)
|
64
|
+
WHERE timeout <= ? AND created_at IS NOT NULL AND (max_running-running IS NULL OR max_running-running > 0)
|
56
65
|
ORDER BY weight IS NOT NULL, weight DESC, timeout ASC
|
57
|
-
LIMIT
|
66
|
+
LIMIT ?
|
58
67
|
SQL
|
68
|
+
end
|
59
69
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
@
|
70
|
+
case url.split('//',2)[0].to_s
|
71
|
+
when /sqlite/i
|
72
|
+
# sqlite always locks tables on BEGIN
|
73
|
+
@table_lock = nil
|
74
|
+
when /mysql/i
|
75
|
+
if config[:disable_resource_limit]
|
76
|
+
@table_lock = "LOCK TABLES `#{@table}` WRITE"
|
77
|
+
else
|
78
|
+
@table_lock = "LOCK TABLES `#{@table}` WRITE, `#{@table}` AS T WRITE"
|
79
|
+
end
|
80
|
+
else
|
81
|
+
@table_lock = "LOCK TABLE `#{@table}`"
|
64
82
|
end
|
83
|
+
|
84
|
+
@prefetch_break_types = config[:prefetch_break_types] || []
|
85
|
+
|
86
|
+
@cleanup_interval = config[:cleanup_interval] || DEFAULT_DELETE_INTERVAL
|
87
|
+
@cleanup_interval_count = 0
|
65
88
|
end
|
66
89
|
|
67
90
|
attr_reader :db
|
68
91
|
|
69
|
-
MAX_SELECT_ROW = 8
|
70
|
-
MAX_RESOURCE = (ENV['PQ_MAX_RESOURCE'] || 4).to_i
|
71
92
|
#KEEPALIVE = 10
|
72
93
|
MAX_RETRY = 10
|
94
|
+
DEFAULT_DELETE_INTERVAL = 20
|
73
95
|
|
74
96
|
def init_database(options)
|
75
97
|
sql = %[
|
@@ -148,42 +170,49 @@ SQL
|
|
148
170
|
now = (options[:now] || Time.now).to_i
|
149
171
|
next_timeout = now + alive_time
|
150
172
|
|
151
|
-
|
173
|
+
tasks = []
|
152
174
|
|
153
175
|
connect {
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
rows += 1
|
177
|
-
}
|
176
|
+
if @cleanup_interval_count <= 0
|
177
|
+
@db["DELETE FROM `#{@table}` WHERE timeout <= ? AND created_at IS NULL", now].delete
|
178
|
+
@cleanup_interval_count = @cleanup_interval
|
179
|
+
end
|
180
|
+
|
181
|
+
@db.transaction do
|
182
|
+
if @table_lock
|
183
|
+
@db[@table_lock].update
|
184
|
+
end
|
185
|
+
|
186
|
+
tasks = []
|
187
|
+
@db.fetch(@sql, now, now, max_acquire) {|row|
|
188
|
+
attributes = create_attributes(nil, row)
|
189
|
+
task_token = Token.new(row[:id])
|
190
|
+
task = AcquiredTask.new(@client, row[:id], attributes, task_token)
|
191
|
+
tasks.push task
|
192
|
+
|
193
|
+
if @prefetch_break_types.include?(attributes[:type])
|
194
|
+
break
|
178
195
|
end
|
179
|
-
|
180
|
-
|
196
|
+
}
|
197
|
+
|
198
|
+
if tasks.empty?
|
199
|
+
return nil
|
181
200
|
end
|
182
|
-
|
183
|
-
|
201
|
+
|
202
|
+
sql = "UPDATE `#{@table}` SET timeout = ? WHERE id IN ("
|
203
|
+
params = [sql, next_timeout]
|
204
|
+
tasks.each {|t| params << t.key }
|
205
|
+
sql << (1..tasks.size).map { '?' }.join(',')
|
206
|
+
sql << ") AND created_at IS NOT NULL"
|
207
|
+
|
208
|
+
n = @db[*params].update
|
209
|
+
if n != tasks.size
|
210
|
+
# TODO table lock doesn't work. error?
|
184
211
|
end
|
185
|
-
|
212
|
+
|
213
|
+
@cleanup_interval_count -= 1
|
186
214
|
end
|
215
|
+
return tasks
|
187
216
|
}
|
188
217
|
end
|
189
218
|
|
data/lib/perfectqueue/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -25,7 +25,9 @@ module QueueTest
|
|
25
25
|
:type => 'rdb_compat',
|
26
26
|
:url => "sqlite://#{database_path}",
|
27
27
|
:table => 'test_tasks',
|
28
|
-
:processor_type => 'thread'
|
28
|
+
:processor_type => 'thread',
|
29
|
+
:cleanup_interval => 0, # for test
|
30
|
+
#:disable_resource_limit => true, # TODO backend-specific test cases
|
29
31
|
}
|
30
32
|
end
|
31
33
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: perfectqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.18
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sequel
|