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.
- data/.gitignore +6 -0
- data/ChangeLog +0 -62
- data/Gemfile +3 -0
- data/README.md +239 -0
- data/Rakefile +19 -0
- data/lib/perfectqueue.rb +68 -4
- data/lib/perfectqueue/application.rb +30 -0
- data/lib/perfectqueue/application/base.rb +27 -0
- data/lib/perfectqueue/application/dispatch.rb +73 -0
- data/lib/perfectqueue/application/router.rb +69 -0
- data/lib/perfectqueue/backend.rb +44 -47
- data/lib/perfectqueue/backend/rdb_compat.rb +298 -0
- data/lib/perfectqueue/blocking_flag.rb +84 -0
- data/lib/perfectqueue/client.rb +117 -0
- data/lib/perfectqueue/command/perfectqueue.rb +108 -323
- data/lib/perfectqueue/daemons_logger.rb +80 -0
- data/lib/perfectqueue/engine.rb +85 -123
- data/lib/perfectqueue/error.rb +53 -0
- data/lib/perfectqueue/model.rb +37 -0
- data/lib/perfectqueue/multiprocess.rb +31 -0
- data/lib/perfectqueue/multiprocess/child_process.rb +108 -0
- data/lib/perfectqueue/multiprocess/child_process_monitor.rb +109 -0
- data/lib/perfectqueue/multiprocess/fork_processor.rb +164 -0
- data/lib/perfectqueue/multiprocess/thread_processor.rb +123 -0
- data/lib/perfectqueue/queue.rb +58 -0
- data/lib/perfectqueue/runner.rb +39 -0
- data/lib/perfectqueue/signal_queue.rb +112 -0
- data/lib/perfectqueue/task.rb +103 -0
- data/lib/perfectqueue/task_metadata.rb +98 -0
- data/lib/perfectqueue/task_monitor.rb +189 -0
- data/lib/perfectqueue/task_status.rb +27 -0
- data/lib/perfectqueue/version.rb +1 -3
- data/lib/perfectqueue/worker.rb +114 -196
- data/perfectqueue.gemspec +24 -0
- data/spec/queue_spec.rb +234 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/worker_spec.rb +81 -0
- metadata +93 -40
- checksums.yaml +0 -7
- data/README.rdoc +0 -224
- data/lib/perfectqueue/backend/null.rb +0 -33
- data/lib/perfectqueue/backend/rdb.rb +0 -181
- data/lib/perfectqueue/backend/simpledb.rb +0 -139
- data/test/backend_test.rb +0 -259
- data/test/cat.sh +0 -2
- data/test/echo.sh +0 -4
- data/test/exec_test.rb +0 -61
- data/test/fail.sh +0 -2
- data/test/huge.sh +0 -2
- data/test/stress.rb +0 -99
- data/test/success.sh +0 -2
- data/test/test_helper.rb +0 -19
@@ -1,33 +0,0 @@
|
|
1
|
-
|
2
|
-
module PerfectQueue
|
3
|
-
|
4
|
-
|
5
|
-
class NullBackend < Backend
|
6
|
-
def list(&block)
|
7
|
-
nil
|
8
|
-
end
|
9
|
-
|
10
|
-
def acquire(timeout, now=Time.now.to_i)
|
11
|
-
nil
|
12
|
-
end
|
13
|
-
|
14
|
-
def finish(token, delete_timeout=3600, now=Time.now.to_i)
|
15
|
-
true
|
16
|
-
end
|
17
|
-
|
18
|
-
def update(token, timeout)
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
|
22
|
-
def cancel(id, delete_timeout=3600, now=Time.now.to_i)
|
23
|
-
true
|
24
|
-
end
|
25
|
-
|
26
|
-
def submit(id, data, time=Time.now.to_i, resource=nil, max_running=nil)
|
27
|
-
true
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
@@ -1,181 +0,0 @@
|
|
1
|
-
|
2
|
-
module PerfectQueue
|
3
|
-
|
4
|
-
|
5
|
-
class RDBBackend < Backend
|
6
|
-
DELETE_OFFSET = 10_0000_0000
|
7
|
-
|
8
|
-
def initialize(uri, table, config={})
|
9
|
-
require 'sequel'
|
10
|
-
require 'uri'
|
11
|
-
|
12
|
-
@uri = uri
|
13
|
-
@table = table
|
14
|
-
|
15
|
-
u = URI.parse(@uri)
|
16
|
-
options = {
|
17
|
-
max_connections: 1,
|
18
|
-
user: u.user,
|
19
|
-
password: u.password,
|
20
|
-
host: u.host,
|
21
|
-
port: u.port ? u.port.to_i : 3306
|
22
|
-
}
|
23
|
-
options[:sslca] = config[:sslca] if config[:sslca]
|
24
|
-
db_name = u.path.split('/')[1]
|
25
|
-
@db = Sequel.mysql2(db_name, options)
|
26
|
-
|
27
|
-
#@last_time = Time.now.to_i
|
28
|
-
@mutex = Mutex.new
|
29
|
-
#init_db(@uri.split('//',2)[0])
|
30
|
-
connect {
|
31
|
-
# connection test
|
32
|
-
}
|
33
|
-
@sql = <<SQL
|
34
|
-
SELECT id, timeout, data, created_at, resource, max_running/running AS weight
|
35
|
-
FROM `#{@table}`
|
36
|
-
LEFT JOIN (
|
37
|
-
SELECT resource AS res, COUNT(1) AS running
|
38
|
-
FROM `#{@table}` AS T
|
39
|
-
WHERE timeout > ? AND created_at IS NOT NULL AND resource IS NOT NULL
|
40
|
-
GROUP BY resource
|
41
|
-
) AS R ON resource = res
|
42
|
-
WHERE timeout <= ? AND (max_running-running IS NULL OR max_running-running > 0)
|
43
|
-
ORDER BY weight IS NOT NULL, weight DESC, timeout ASC
|
44
|
-
LIMIT #{MAX_SELECT_ROW}
|
45
|
-
SQL
|
46
|
-
# sqlite doesn't support SELECT ... FOR UPDATE but
|
47
|
-
# sqlite doesn't need it because the db is not shared
|
48
|
-
unless @uri.split('//',2)[0].to_s.include?('sqlite')
|
49
|
-
@sql << 'FOR UPDATE'
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def create_tables
|
54
|
-
sql = ''
|
55
|
-
sql << "CREATE TABLE IF NOT EXISTS `#{@table}` ("
|
56
|
-
sql << " id VARCHAR(256) NOT NULL,"
|
57
|
-
sql << " timeout INT NOT NULL,"
|
58
|
-
sql << " data BLOB NOT NULL,"
|
59
|
-
sql << " created_at INT,"
|
60
|
-
sql << " resource VARCHAR(256),"
|
61
|
-
sql << " max_running INT,"
|
62
|
-
sql << " PRIMARY KEY (id)"
|
63
|
-
sql << ");"
|
64
|
-
# TODO index
|
65
|
-
connect {
|
66
|
-
@db.run sql
|
67
|
-
}
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
def connect(&block)
|
72
|
-
#now = Time.now.to_i
|
73
|
-
@mutex.synchronize do
|
74
|
-
#if now - @last_time > KEEPALIVE
|
75
|
-
# @db.disconnect
|
76
|
-
#end
|
77
|
-
#@last_time = now
|
78
|
-
retry_count = 0
|
79
|
-
begin
|
80
|
-
block.call
|
81
|
-
rescue
|
82
|
-
# workaround for "Mysql2::Error: Deadlock found when trying to get lock; try restarting transaction" error
|
83
|
-
if $!.to_s.include?('try restarting transaction')
|
84
|
-
err = ([$!] + $!.backtrace.map {|bt| " #{bt}" }).join("\n")
|
85
|
-
retry_count += 1
|
86
|
-
if retry_count < MAX_RETRY
|
87
|
-
STDERR.puts err + "\n retrying."
|
88
|
-
sleep 0.5
|
89
|
-
retry
|
90
|
-
else
|
91
|
-
STDERR.puts err + "\n abort."
|
92
|
-
end
|
93
|
-
end
|
94
|
-
raise
|
95
|
-
ensure
|
96
|
-
@db.disconnect
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
public
|
102
|
-
def list(&block)
|
103
|
-
@db.fetch("SELECT id, timeout, data, created_at, resource FROM `#{@table}` WHERE created_at IS NOT NULL ORDER BY timeout ASC;") {|row|
|
104
|
-
yield row[:id], row[:created_at], row[:data], row[:timeout], row[:resource]
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
MAX_SELECT_ROW = 8
|
109
|
-
#KEEPALIVE = 10
|
110
|
-
MAX_RETRY = 10
|
111
|
-
|
112
|
-
def acquire(timeout, now=Time.now.to_i)
|
113
|
-
connect {
|
114
|
-
while true
|
115
|
-
rows = 0
|
116
|
-
@db.transaction do
|
117
|
-
@db.fetch(@sql, now, now) {|row|
|
118
|
-
unless row[:created_at]
|
119
|
-
# finished/canceled task
|
120
|
-
@db["DELETE FROM `#{@table}` WHERE id=?;", row[:id]].delete
|
121
|
-
|
122
|
-
else
|
123
|
-
## optimistic lock is not needed because the row is locked for update
|
124
|
-
#n = @db["UPDATE `#{@table}` SET timeout=? WHERE id=? AND timeout=?", timeout, row[:id], row[:timeout]].update
|
125
|
-
n = @db["UPDATE `#{@table}` SET timeout=? WHERE id=?", timeout, row[:id]].update
|
126
|
-
if n > 0
|
127
|
-
return row[:id], Task.new(row[:id], row[:created_at], row[:data], row[:resource])
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
rows += 1
|
132
|
-
}
|
133
|
-
end
|
134
|
-
break nil if rows < MAX_SELECT_ROW
|
135
|
-
end
|
136
|
-
}
|
137
|
-
end
|
138
|
-
|
139
|
-
def finish(id, delete_timeout=3600, now=Time.now.to_i)
|
140
|
-
connect {
|
141
|
-
n = @db["UPDATE `#{@table}` SET timeout=?, created_at=NULL, resource=NULL WHERE id=? AND created_at IS NOT NULL;", now+delete_timeout-DELETE_OFFSET, id].update
|
142
|
-
return n > 0
|
143
|
-
}
|
144
|
-
end
|
145
|
-
|
146
|
-
def update(id, timeout)
|
147
|
-
connect {
|
148
|
-
n = @db["UPDATE `#{@table}` SET timeout=? WHERE id=? AND created_at IS NOT NULL;", timeout, id].update
|
149
|
-
if n <= 0
|
150
|
-
raise CanceledError, "Task id=#{id} is canceled."
|
151
|
-
end
|
152
|
-
return nil
|
153
|
-
}
|
154
|
-
end
|
155
|
-
|
156
|
-
def cancel(id, delete_timeout=3600, now=Time.now.to_i)
|
157
|
-
finish(id, delete_timeout, now)
|
158
|
-
end
|
159
|
-
|
160
|
-
def submit(id, data, time=Time.now.to_i, resource=nil, max_running=nil)
|
161
|
-
connect {
|
162
|
-
begin
|
163
|
-
data = Sequel::SQL::Blob.new(data)
|
164
|
-
n = @db["INSERT INTO `#{@table}` (id, timeout, data, created_at, resource, max_running) VALUES (?, ?, ?, ?, ?, ?);", id, time, data, time, resource, max_running].insert
|
165
|
-
return true
|
166
|
-
rescue Sequel::DatabaseError => e
|
167
|
-
# Sequel doesn't provide error classes to distinguish duplicate-entry from other
|
168
|
-
# errors like connectivity error. This code assumes the driver is mysql2 and
|
169
|
-
# the error message is "Mysql::ServerError::DupEntry: Duplicate entry"
|
170
|
-
if /: Duplicate entry/ =~ e.to_s
|
171
|
-
return nil
|
172
|
-
end
|
173
|
-
raise e
|
174
|
-
end
|
175
|
-
}
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
end
|
181
|
-
|
@@ -1,139 +0,0 @@
|
|
1
|
-
|
2
|
-
module PerfectQueue
|
3
|
-
|
4
|
-
|
5
|
-
class SimpleDBBackend < Backend
|
6
|
-
def initialize(key_id, secret_key, domain)
|
7
|
-
require 'aws-sdk'
|
8
|
-
@consistent_read = false
|
9
|
-
|
10
|
-
@db = AWS::SimpleDB.new(
|
11
|
-
:access_key_id => key_id,
|
12
|
-
:secret_access_key => secret_key)
|
13
|
-
|
14
|
-
@domain_name = domain
|
15
|
-
@domain = @db.domains[@domain_name]
|
16
|
-
unless @domain.exists?
|
17
|
-
@domain = @db.domains.create(@domain_name)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_accessor :consistent_read
|
22
|
-
|
23
|
-
def use_consistent_read(b=true)
|
24
|
-
@consistent_read = b
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
def list(&block)
|
29
|
-
# TODO support resource limit
|
30
|
-
@domain.items.select('timeout', 'data', 'created_at',
|
31
|
-
:where => "created_at != '' AND timeout > '#{int_encode(0)}'",
|
32
|
-
:order => [:timeout, :asc],
|
33
|
-
:consistent_read => @consistent_read) {|itemdata|
|
34
|
-
id = itemdata.name
|
35
|
-
attrs = itemdata.attributes
|
36
|
-
next unless attrs['created_at'].first
|
37
|
-
created_at = int_decode(attrs['created_at'].first)
|
38
|
-
data = attrs['data'].first
|
39
|
-
timeout = int_decode(attrs['timeout'].first)
|
40
|
-
yield id, created_at, data, timeout, nil
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
MAX_SELECT_ROW = 4
|
45
|
-
|
46
|
-
def acquire(timeout, now=Time.now.to_i)
|
47
|
-
while true
|
48
|
-
# TODO support resource limit
|
49
|
-
rows = 0
|
50
|
-
@domain.items.select('timeout', 'data', 'created_at',
|
51
|
-
:where => "timeout <= '#{int_encode(now)}'",
|
52
|
-
:order => [:timeout, :asc],
|
53
|
-
:consistent_read => @consistent_read,
|
54
|
-
:limit => MAX_SELECT_ROW) {|itemdata|
|
55
|
-
begin
|
56
|
-
id = itemdata.name
|
57
|
-
attrs = itemdata.attributes
|
58
|
-
salt = attrs['created_at'].first
|
59
|
-
|
60
|
-
if !salt || salt.empty?
|
61
|
-
# finished/canceled task
|
62
|
-
@domain.items[id].delete(:if=>{'created_at'=>''})
|
63
|
-
|
64
|
-
else
|
65
|
-
created_at = int_decode(salt)
|
66
|
-
@domain.items[id].attributes.replace('timeout'=>int_encode(timeout),
|
67
|
-
:if=>{'timeout'=>attrs['timeout'].first})
|
68
|
-
|
69
|
-
data = attrs['data'].first
|
70
|
-
|
71
|
-
return [id,salt], Task.new(id, created_at, data, nil)
|
72
|
-
end
|
73
|
-
|
74
|
-
rescue AWS::SimpleDB::Errors::ConditionalCheckFailed, AWS::SimpleDB::Errors::AttributeDoesNotExist
|
75
|
-
end
|
76
|
-
|
77
|
-
rows += 1
|
78
|
-
}
|
79
|
-
if rows < MAX_SELECT_ROW
|
80
|
-
return nil
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def finish(token, delete_timeout=3600, now=Time.now.to_i)
|
86
|
-
begin
|
87
|
-
id, salt = *token
|
88
|
-
@domain.items[id].attributes.replace('timeout'=>int_encode(now+delete_timeout), 'created_at'=>'',
|
89
|
-
:if=>{'created_at'=>salt})
|
90
|
-
return true
|
91
|
-
rescue AWS::SimpleDB::Errors::ConditionalCheckFailed, AWS::SimpleDB::Errors::AttributeDoesNotExist
|
92
|
-
return false
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def update(token, timeout)
|
97
|
-
begin
|
98
|
-
id, salt = *token
|
99
|
-
@domain.items[id].attributes.replace('timeout'=>int_encode(timeout),
|
100
|
-
:if=>{'created_at'=>salt})
|
101
|
-
rescue AWS::SimpleDB::Errors::ConditionalCheckFailed, AWS::SimpleDB::Errors::AttributeDoesNotExist
|
102
|
-
raise CanceledError, "Task id=#{id} is canceled."
|
103
|
-
end
|
104
|
-
nil
|
105
|
-
end
|
106
|
-
|
107
|
-
def cancel(id, delete_timeout=3600, now=Time.now.to_i)
|
108
|
-
salt = @domain.items[id].attributes['created_at'].first
|
109
|
-
unless salt
|
110
|
-
return false
|
111
|
-
end
|
112
|
-
token = [id,salt]
|
113
|
-
finish(token, delete_timeout, now)
|
114
|
-
end
|
115
|
-
|
116
|
-
def submit(id, data, time=Time.now.to_i, resource=nil)
|
117
|
-
# TODO support resource limit
|
118
|
-
begin
|
119
|
-
@domain.items[id].attributes.replace('timeout'=>int_encode(time), 'created_at'=>int_encode(time), 'data'=>data,
|
120
|
-
:unless=>'timeout')
|
121
|
-
return true
|
122
|
-
rescue AWS::SimpleDB::Errors::ConditionalCheckFailed, AWS::SimpleDB::Errors::ExistsAndExpectedValue
|
123
|
-
return nil
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
private
|
128
|
-
def int_encode(num)
|
129
|
-
"%08x" % num
|
130
|
-
end
|
131
|
-
|
132
|
-
def int_decode(str)
|
133
|
-
str.to_i(16)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
|
138
|
-
end
|
139
|
-
|
data/test/backend_test.rb
DELETED
@@ -1,259 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__)+'/test_helper'
|
2
|
-
|
3
|
-
class BackendTest < Test::Unit::TestCase
|
4
|
-
TIMEOUT = 10
|
5
|
-
DB_PATH = File.dirname(__FILE__)+'/test.db'
|
6
|
-
DB_URI = "sqlite://#{DB_PATH}"
|
7
|
-
|
8
|
-
def clean_backend
|
9
|
-
@key_prefix = "test-#{"%08x"%rand(2**32)}-"
|
10
|
-
db = open_backend
|
11
|
-
db.list {|id,created_at,data,timeout|
|
12
|
-
db.cancel(id)
|
13
|
-
}
|
14
|
-
FileUtils.rm_f DB_PATH
|
15
|
-
end
|
16
|
-
|
17
|
-
def open_backend
|
18
|
-
#PerfectQueue::SimpleDBBackend.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'], 'perfectqueue-test-1').use_consistent_read
|
19
|
-
db = PerfectQueue::RDBBackend.new(DB_URI, "perfectdb_test")
|
20
|
-
db.create_tables
|
21
|
-
db
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'acquire' do
|
25
|
-
clean_backend
|
26
|
-
|
27
|
-
db1 = open_backend
|
28
|
-
db2 = open_backend
|
29
|
-
db3 = open_backend
|
30
|
-
|
31
|
-
time = Time.now.to_i
|
32
|
-
|
33
|
-
ok = db1.submit(@key_prefix+'test1', 'data1', time)
|
34
|
-
assert_equal true, ok
|
35
|
-
|
36
|
-
token, task = db2.acquire(time+TIMEOUT)
|
37
|
-
assert_not_equal nil, task
|
38
|
-
assert_equal @key_prefix+'test1', task.id
|
39
|
-
assert_equal time, task.created_at
|
40
|
-
assert_equal 'data1', task.data
|
41
|
-
|
42
|
-
token_, task_ = db3.acquire(time+TIMEOUT)
|
43
|
-
assert_equal nil, token_
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'finish' do
|
47
|
-
clean_backend
|
48
|
-
|
49
|
-
db1 = open_backend
|
50
|
-
db2 = open_backend
|
51
|
-
|
52
|
-
time = Time.now.to_i
|
53
|
-
|
54
|
-
ok = db1.submit(@key_prefix+'test1', 'data1', time)
|
55
|
-
assert_equal true, ok
|
56
|
-
|
57
|
-
token, task = db1.acquire(time+TIMEOUT)
|
58
|
-
assert_not_equal nil, task
|
59
|
-
|
60
|
-
ok = db1.finish(token)
|
61
|
-
assert_equal true, ok
|
62
|
-
|
63
|
-
token_, task_ = db2.acquire(time+TIMEOUT)
|
64
|
-
assert_equal nil, token_
|
65
|
-
|
66
|
-
ok = db1.finish(token)
|
67
|
-
assert_equal false, ok
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'canceled' do
|
71
|
-
clean_backend
|
72
|
-
|
73
|
-
db1 = open_backend
|
74
|
-
db2 = open_backend
|
75
|
-
|
76
|
-
time = Time.now.to_i
|
77
|
-
|
78
|
-
ok = db1.submit(@key_prefix+'test1', 'data1', time)
|
79
|
-
assert_equal true, ok
|
80
|
-
|
81
|
-
token, task = db1.acquire(time+TIMEOUT)
|
82
|
-
assert_not_equal nil, task
|
83
|
-
|
84
|
-
ok = db1.cancel(task.id)
|
85
|
-
assert_equal true, ok
|
86
|
-
|
87
|
-
token_, task_ = db2.acquire(time+TIMEOUT)
|
88
|
-
assert_equal nil, token_
|
89
|
-
|
90
|
-
assert_raise(PerfectQueue::CanceledError) do
|
91
|
-
db1.update(token, time+TIMEOUT)
|
92
|
-
end
|
93
|
-
|
94
|
-
ok = db1.cancel(task.id)
|
95
|
-
assert_equal false, ok
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'order' do
|
99
|
-
clean_backend
|
100
|
-
|
101
|
-
db1 = open_backend
|
102
|
-
db2 = open_backend
|
103
|
-
db3 = open_backend
|
104
|
-
|
105
|
-
time = Time.now.to_i
|
106
|
-
|
107
|
-
ok = db1.submit(@key_prefix+'test1', 'data1', time)
|
108
|
-
assert_equal true, ok
|
109
|
-
|
110
|
-
ok = db1.submit(@key_prefix+'test2', 'data2', time-1)
|
111
|
-
assert_equal true, ok
|
112
|
-
|
113
|
-
ok = db1.submit(@key_prefix+'test3', 'data3', time+1)
|
114
|
-
assert_equal true, ok
|
115
|
-
|
116
|
-
token, task = db2.acquire(time+TIMEOUT, time+1)
|
117
|
-
assert_not_equal nil, task
|
118
|
-
assert_equal @key_prefix+'test2', task.id
|
119
|
-
assert_equal time-1, task.created_at
|
120
|
-
assert_equal 'data2', task.data
|
121
|
-
|
122
|
-
token, task = db2.acquire(time+TIMEOUT, time+1)
|
123
|
-
assert_not_equal nil, task
|
124
|
-
assert_equal @key_prefix+'test1', task.id
|
125
|
-
assert_equal time, task.created_at
|
126
|
-
assert_equal 'data1', task.data
|
127
|
-
|
128
|
-
token, task = db2.acquire(time+TIMEOUT, time+1)
|
129
|
-
assert_not_equal nil, task
|
130
|
-
assert_equal @key_prefix+'test3', task.id
|
131
|
-
assert_equal time+1, task.created_at
|
132
|
-
assert_equal 'data3', task.data
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'timeout' do
|
136
|
-
clean_backend
|
137
|
-
|
138
|
-
db1 = open_backend
|
139
|
-
db2 = open_backend
|
140
|
-
|
141
|
-
time = Time.now.to_i
|
142
|
-
|
143
|
-
ok = db1.submit(@key_prefix+'test1', 'data1', time)
|
144
|
-
assert_equal true, ok
|
145
|
-
|
146
|
-
token, task = db1.acquire(time+TIMEOUT)
|
147
|
-
assert_not_equal nil, task
|
148
|
-
assert_equal @key_prefix+'test1', task.id
|
149
|
-
assert_equal time, task.created_at
|
150
|
-
assert_equal 'data1', task.data
|
151
|
-
|
152
|
-
token, task = db2.acquire(time+TIMEOUT*2, time+TIMEOUT)
|
153
|
-
assert_not_equal nil, task
|
154
|
-
assert_equal @key_prefix+'test1', task.id
|
155
|
-
assert_equal time, task.created_at
|
156
|
-
assert_equal 'data1', task.data
|
157
|
-
end
|
158
|
-
|
159
|
-
it 'extend' do
|
160
|
-
clean_backend
|
161
|
-
|
162
|
-
db1 = open_backend
|
163
|
-
db2 = open_backend
|
164
|
-
|
165
|
-
time = Time.now.to_i
|
166
|
-
|
167
|
-
ok = db1.submit(@key_prefix+'test1', 'data1', time)
|
168
|
-
assert_equal true, ok
|
169
|
-
|
170
|
-
token, task = db1.acquire(time+TIMEOUT)
|
171
|
-
assert_not_equal nil, task
|
172
|
-
|
173
|
-
assert_nothing_raised do
|
174
|
-
db1.update(token, time+TIMEOUT+1)
|
175
|
-
end
|
176
|
-
|
177
|
-
token_, task_ = db2.acquire(time+TIMEOUT, time)
|
178
|
-
assert_equal nil, token_
|
179
|
-
|
180
|
-
token, task = db2.acquire(time+TIMEOUT*2, time+TIMEOUT+1)
|
181
|
-
assert_not_equal nil, task
|
182
|
-
assert_equal @key_prefix+'test1', task.id
|
183
|
-
assert_equal time, task.created_at
|
184
|
-
assert_equal 'data1', task.data
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'release' do
|
188
|
-
clean_backend
|
189
|
-
|
190
|
-
db1 = open_backend
|
191
|
-
db2 = open_backend
|
192
|
-
|
193
|
-
time = Time.now.to_i
|
194
|
-
|
195
|
-
ok = db1.submit(@key_prefix+'test1', 'data1', time)
|
196
|
-
assert_equal true, ok
|
197
|
-
|
198
|
-
token, task = db1.acquire(time+TIMEOUT)
|
199
|
-
assert_not_equal nil, task
|
200
|
-
|
201
|
-
assert_nothing_raised do
|
202
|
-
db1.update(token, time+TIMEOUT+1)
|
203
|
-
end
|
204
|
-
|
205
|
-
token_, task_ = db2.acquire(time+TIMEOUT, time)
|
206
|
-
assert_equal nil, token_
|
207
|
-
|
208
|
-
assert_nothing_raised do
|
209
|
-
db1.update(token, time)
|
210
|
-
end
|
211
|
-
|
212
|
-
token, task = db2.acquire(time+TIMEOUT, time)
|
213
|
-
assert_not_equal nil, task
|
214
|
-
assert_equal @key_prefix+'test1', task.id
|
215
|
-
assert_equal time, task.created_at
|
216
|
-
assert_equal 'data1', task.data
|
217
|
-
end
|
218
|
-
|
219
|
-
it 'resource limit' do
|
220
|
-
clean_backend
|
221
|
-
|
222
|
-
db1 = open_backend
|
223
|
-
|
224
|
-
time = Time.now.to_i
|
225
|
-
|
226
|
-
3.times do |i|
|
227
|
-
ok = db1.submit(@key_prefix+'test'+i.to_s, 'data1', time-(i+1), 'user1', 2)
|
228
|
-
assert_equal true, ok
|
229
|
-
end
|
230
|
-
ok = db1.submit(@key_prefix+'test5', 'data2', time, 'user2', 2)
|
231
|
-
assert_equal true, ok
|
232
|
-
|
233
|
-
token_1 = nil
|
234
|
-
task_1 = nil
|
235
|
-
|
236
|
-
token_1, task_1 = db1.acquire(time+TIMEOUT, time)
|
237
|
-
assert_not_equal nil, task_1
|
238
|
-
assert_equal "user1", task_1.resource
|
239
|
-
|
240
|
-
token, task = db1.acquire(time+TIMEOUT, time)
|
241
|
-
assert_not_equal nil, task
|
242
|
-
assert_equal "user2", task.resource
|
243
|
-
|
244
|
-
token, task = db1.acquire(time+TIMEOUT, time)
|
245
|
-
assert_not_equal nil, task
|
246
|
-
assert_equal "user1", task.resource
|
247
|
-
|
248
|
-
token, task = db1.acquire(time+TIMEOUT, time)
|
249
|
-
assert_equal nil, task
|
250
|
-
|
251
|
-
ok = db1.finish(token_1)
|
252
|
-
assert_equal true, ok
|
253
|
-
|
254
|
-
token, task = db1.acquire(time+TIMEOUT, time)
|
255
|
-
assert_not_equal nil, task
|
256
|
-
assert_equal "user1", task.resource
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|