perfectqueue 0.8.43 → 0.8.44
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.
- checksums.yaml +4 -4
- data/.travis.yml +8 -0
- data/ChangeLog +5 -0
- data/Gemfile +2 -0
- data/README.md +11 -0
- data/circle.yml +7 -0
- data/lib/perfectqueue/backend/rdb_compat.rb +38 -26
- data/lib/perfectqueue/version.rb +1 -1
- data/perfectqueue.gemspec +2 -1
- data/spec/rdb_compat_backend_spec.rb +1 -6
- data/spec/spec_helper.rb +7 -7
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6f5457263e6492b228864dbc72be480b28ea20f
|
4
|
+
data.tar.gz: d83d97c23703a464f88db7343615dd856cd925ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9cdd377afec8f82f13162b92073864e8d2deac00cf705a51409f3fe1343ab5a5d6716d2ed4a11daa50cd76c15bb4a9fbdbdba565003fe7673ead6fc979d2043
|
7
|
+
data.tar.gz: fbf7ef421de36a66fa9a1712f3fa0dcb59d9b7d648a77dd052bbb6f8c0006549165c0a8f04be4e3894dbb78c15badba37eb381a8bcf5822e9ae3bfabd948b164
|
data/.travis.yml
CHANGED
data/ChangeLog
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# PerfectQueue
|
2
2
|
|
3
3
|
[](https://travis-ci.org/treasure-data/perfectqueue)
|
4
|
+
[](https://coveralls.io/github/treasure-data/perfectqueue?branch=master)
|
4
5
|
|
5
6
|
PerfectQueue is a highly available distributed queue built on top of RDBMS.
|
6
7
|
PerfectQueue provides similar API to Amazon SQS, while PerfectQueue focues on reliability and flexible scheduling rather than scalability.
|
@@ -246,3 +247,13 @@ options for run:
|
|
246
247
|
|
247
248
|
$ perfectqueue run -I. -Ilib -rconfig/boot.rb -rapps/workers/task_dispatch.rb TaskDispatch
|
248
249
|
|
250
|
+
## Test
|
251
|
+
|
252
|
+
Running spec utilize 'mysql2://root:@localhost/perfectqueue_test' as the connection string.
|
253
|
+
Please install MySQL server at localhost then run;
|
254
|
+
|
255
|
+
$ mysql -h localhost -u root -e 'create database perfectqueue_test;'
|
256
|
+
|
257
|
+
You can run spec.
|
258
|
+
|
259
|
+
$ bundle exec rake spec
|
data/circle.yml
ADDED
@@ -81,7 +81,7 @@ LIMIT ?
|
|
81
81
|
SQL
|
82
82
|
else
|
83
83
|
@sql = <<SQL
|
84
|
-
SELECT id, timeout, data, created_at, resource, max_running, max_running/running AS weight
|
84
|
+
SELECT id, timeout, data, created_at, resource, max_running, IFNULL(max_running, 1) / (IFNULL(running, 0) + 1) AS weight
|
85
85
|
FROM `#{@table}`
|
86
86
|
LEFT JOIN (
|
87
87
|
SELECT resource AS res, COUNT(1) AS running
|
@@ -90,7 +90,7 @@ LEFT JOIN (
|
|
90
90
|
GROUP BY resource
|
91
91
|
) AS R ON resource = res
|
92
92
|
WHERE timeout <= ? AND created_at IS NOT NULL AND (max_running-running IS NULL OR max_running-running > 0)
|
93
|
-
ORDER BY weight
|
93
|
+
ORDER BY weight DESC, timeout ASC
|
94
94
|
LIMIT ?
|
95
95
|
SQL
|
96
96
|
end
|
@@ -101,14 +101,22 @@ SQL
|
|
101
101
|
@table_lock = nil
|
102
102
|
@table_unlock = nil
|
103
103
|
when /mysql/i
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
104
|
+
@table_lock = lambda {
|
105
|
+
locked = nil
|
106
|
+
loop do
|
107
|
+
@db.fetch("SELECT GET_LOCK('#{@table}', #{LOCK_WAIT_TIMEOUT}) locked") do |row|
|
108
|
+
locked = true if row[:locked] == 1
|
109
|
+
end
|
110
|
+
break if locked
|
111
|
+
end
|
112
|
+
}
|
113
|
+
@table_unlock = lambda {
|
114
|
+
@db.run("SELECT RELEASE_LOCK('#{@table}')")
|
115
|
+
}
|
110
116
|
else
|
111
|
-
@table_lock =
|
117
|
+
@table_lock = lambda {
|
118
|
+
@db.run("LOCK TABLE `#{@table}`")
|
119
|
+
}
|
112
120
|
@table_unlock = nil
|
113
121
|
end
|
114
122
|
|
@@ -122,21 +130,26 @@ SQL
|
|
122
130
|
|
123
131
|
KEEPALIVE = 10
|
124
132
|
MAX_RETRY = 10
|
133
|
+
LOCK_WAIT_TIMEOUT = 60
|
125
134
|
DEFAULT_DELETE_INTERVAL = 20
|
126
135
|
|
127
136
|
def init_database(options)
|
128
|
-
sql =
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
137
|
+
sql = []
|
138
|
+
sql << "DROP TABLE IF EXISTS `#{@table}`" if options[:force]
|
139
|
+
sql << <<-SQL
|
140
|
+
CREATE TABLE IF NOT EXISTS `#{@table}` (
|
141
|
+
id VARCHAR(255) NOT NULL,
|
142
|
+
timeout INT NOT NULL,
|
143
|
+
data LONGBLOB NOT NULL,
|
144
|
+
created_at INT,
|
145
|
+
resource VARCHAR(255),
|
146
|
+
max_running INT,
|
147
|
+
PRIMARY KEY (id)
|
148
|
+
)
|
149
|
+
SQL
|
150
|
+
sql << "CREATE INDEX `index_#{@table}_on_timeout` ON `#{@table}` (`timeout`)"
|
138
151
|
connect {
|
139
|
-
|
152
|
+
sql.each(&@db.method(:run))
|
140
153
|
}
|
141
154
|
end
|
142
155
|
|
@@ -164,8 +177,7 @@ SQL
|
|
164
177
|
now = (options[:now] || Time.now).to_i
|
165
178
|
|
166
179
|
connect {
|
167
|
-
|
168
|
-
@db.fetch("SELECT id, timeout, data, created_at, resource, max_running FROM `#{@table}` ORDER BY timeout ASC", now) {|row|
|
180
|
+
@db.fetch("SELECT id, timeout, data, created_at, resource, max_running FROM `#{@table}` ORDER BY timeout ASC") {|row|
|
169
181
|
attributes = create_attributes(now, row)
|
170
182
|
task = TaskWithMetadata.new(@client, row[:id], attributes)
|
171
183
|
yield task
|
@@ -203,7 +215,7 @@ SQL
|
|
203
215
|
|
204
216
|
connect {
|
205
217
|
begin
|
206
|
-
|
218
|
+
@db[
|
207
219
|
"INSERT INTO `#{@table}` (id, timeout, data, created_at, resource, max_running) VALUES (?, ?, ?, ?, ?, ?)",
|
208
220
|
key, run_at, d, now, user, max_running
|
209
221
|
].insert
|
@@ -341,7 +353,7 @@ SQL
|
|
341
353
|
begin
|
342
354
|
@db.transaction do
|
343
355
|
if @table_lock
|
344
|
-
@
|
356
|
+
@table_lock.call
|
345
357
|
locked = true
|
346
358
|
end
|
347
359
|
|
@@ -350,7 +362,7 @@ SQL
|
|
350
362
|
|
351
363
|
ensure
|
352
364
|
if @use_connection_pooling && locked
|
353
|
-
@
|
365
|
+
@table_unlock.call
|
354
366
|
end
|
355
367
|
end
|
356
368
|
}
|
@@ -437,7 +449,7 @@ SQL
|
|
437
449
|
type = row[:id].split(/\./, 2)[0]
|
438
450
|
end
|
439
451
|
|
440
|
-
|
452
|
+
{
|
441
453
|
:status => status,
|
442
454
|
:created_at => created_at,
|
443
455
|
:data => data,
|
data/lib/perfectqueue/version.rb
CHANGED
data/perfectqueue.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.add_dependency "sequel", "~> 3.48.0"
|
21
21
|
gem.add_development_dependency "rake", "~> 0.9.2"
|
22
22
|
gem.add_development_dependency "rspec", "~> 2.10.0"
|
23
|
-
gem.add_development_dependency "simplecov", "~> 0.
|
23
|
+
gem.add_development_dependency "simplecov", "~> 0.10.0"
|
24
24
|
gem.add_development_dependency "sqlite3", "~> 1.3.3"
|
25
|
+
gem.add_development_dependency "mysql2", "~> 0.3.20"
|
25
26
|
end
|
@@ -2,12 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'perfectqueue/backend/rdb_compat'
|
3
3
|
|
4
4
|
describe Backend::RDBCompatBackend do
|
5
|
-
|
6
|
-
FileUtils.rm_f 'spec/test.db'
|
7
|
-
queue = PerfectQueue.open({:type=>'rdb_compat', :url=>'sqlite://spec/test.db', :table=>'test_tasks', :processor_type=>'thread'})
|
8
|
-
queue.client.init_database
|
9
|
-
queue
|
10
|
-
end
|
5
|
+
include QueueTest
|
11
6
|
|
12
7
|
let :client do
|
13
8
|
queue.client
|
data/spec/spec_helper.rb
CHANGED
@@ -11,19 +11,20 @@ if ENV['SIMPLE_COV']
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
+
if ENV["CI"]
|
15
|
+
require 'coveralls'
|
16
|
+
Coveralls.wear!
|
17
|
+
end
|
18
|
+
|
14
19
|
require 'fileutils'
|
15
20
|
|
16
21
|
module QueueTest
|
17
22
|
def self.included(mod)
|
18
23
|
mod.module_eval do
|
19
|
-
let :database_path do
|
20
|
-
'spec/test.db'
|
21
|
-
end
|
22
|
-
|
23
24
|
let :queue_config do
|
24
25
|
{
|
25
26
|
:type => 'rdb_compat',
|
26
|
-
:url => "
|
27
|
+
:url => "mysql2://root:@localhost/perfectqueue_test",
|
27
28
|
:table => 'test_tasks',
|
28
29
|
:processor_type => 'thread',
|
29
30
|
:cleanup_interval => 0, # for test
|
@@ -36,8 +37,7 @@ module QueueTest
|
|
36
37
|
end
|
37
38
|
|
38
39
|
before do
|
39
|
-
|
40
|
-
queue.client.init_database
|
40
|
+
queue.client.init_database(:force => true)
|
41
41
|
end
|
42
42
|
|
43
43
|
after do
|
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.8.
|
4
|
+
version: 0.8.44
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.10.0
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 0.10.0
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: sqlite3
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 1.3.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mysql2
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.3.20
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.3.20
|
83
97
|
description: Highly available distributed cron built on RDBMS
|
84
98
|
email: frsyuki@gmail.com
|
85
99
|
executables:
|
@@ -96,6 +110,7 @@ files:
|
|
96
110
|
- README.md
|
97
111
|
- Rakefile
|
98
112
|
- bin/perfectqueue
|
113
|
+
- circle.yml
|
99
114
|
- lib/perfectqueue.rb
|
100
115
|
- lib/perfectqueue/application.rb
|
101
116
|
- lib/perfectqueue/application/base.rb
|
@@ -153,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
168
|
version: '0'
|
154
169
|
requirements: []
|
155
170
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.4.5
|
171
|
+
rubygems_version: 2.4.5.1
|
157
172
|
signing_key:
|
158
173
|
specification_version: 4
|
159
174
|
summary: Highly available distributed cron built on RDBMS
|