queue_classic 3.0.0rc → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/queue_classic/install_generator.rb +7 -1
- data/lib/generators/queue_classic/templates/update_queue_classic_3_0_0.rb +9 -0
- data/lib/queue_classic.rb +24 -4
- data/lib/queue_classic/conn_adapter.rb +2 -2
- data/lib/queue_classic/queue.rb +13 -5
- data/lib/queue_classic/setup.rb +23 -2
- data/lib/queue_classic/tasks.rb +5 -0
- data/lib/queue_classic/worker.rb +15 -5
- data/readme.md +39 -4
- data/sql/create_table.sql +3 -1
- data/sql/ddl.sql +5 -2
- data/sql/downgrade_from_3_0_0.sql +2 -0
- data/sql/update_to_3_0_0.sql +17 -0
- data/test/helper.rb +9 -0
- data/test/lib/queue_classic_test.rb +32 -0
- data/test/queue_test.rb +8 -6
- data/test/worker_test.rb +2 -4
- metadata +17 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3558784567b56e6d75e1c872aaecf392e2bbfcf7
|
4
|
+
data.tar.gz: e4f6f925b2db3333b93216b4caee0ebe76ee0662
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c82dbc205598a39eb6d0d35dec8accaeb5a7cf3b0dea45cd76a9a9b55c4fab6802b0eb86720b9805f0a37abe23919873706386063b4ec52f3050ea2d22c9ed1f
|
7
|
+
data.tar.gz: d14075365a1c02a36350ce9c6fc986772425abda40e8ce45bdf97eb55e91979d970b57339c735cf135ec6878aaa353790b7fda9c1cebca2e9124ec9c1000bed4
|
@@ -16,7 +16,13 @@ module QC
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def create_migration_file
|
19
|
-
|
19
|
+
if self.class.migration_exists?('db/migrate', 'add_queue_classic').nil?
|
20
|
+
migration_template 'add_queue_classic.rb', 'db/migrate/add_queue_classic.rb'
|
21
|
+
end
|
22
|
+
|
23
|
+
if self.class.migration_exists?('db/migrate', 'update_queue_classic_3_0_0').nil?
|
24
|
+
migration_template 'update_queue_classic_3_0_0.rb', 'db/migrate/update_queue_classic_3_0_0.rb'
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
data/lib/queue_classic.rb
CHANGED
@@ -52,10 +52,18 @@ module QC
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
def self.has_connection?
|
56
|
+
!@conn_adapter.nil?
|
57
|
+
end
|
58
|
+
|
55
59
|
def self.default_conn_adapter
|
56
60
|
@conn_adapter ||= ConnAdapter.new
|
57
61
|
end
|
58
62
|
|
63
|
+
def self.default_conn_adapter=(conn)
|
64
|
+
@conn_adapter = conn
|
65
|
+
end
|
66
|
+
|
59
67
|
def self.log_yield(data)
|
60
68
|
begin
|
61
69
|
t0 = Time.now
|
@@ -83,9 +91,21 @@ module QC
|
|
83
91
|
puts(out) if ENV["DEBUG"]
|
84
92
|
return result
|
85
93
|
end
|
94
|
+
|
95
|
+
def self.measure(data)
|
96
|
+
if ENV['QC_MEASURE']
|
97
|
+
$stdout.puts("measure#qc.#{data}")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# This will unlock all jobs any postgres' PID that is not existing anymore
|
102
|
+
# to prevent any infinitely locked jobs
|
103
|
+
def self.unlock_jobs_of_dead_workers
|
104
|
+
@conn_adapter.execute("UPDATE #{QC::TABLE_NAME} SET locked_at = NULL, locked_by = NULL WHERE locked_by NOT IN (SELECT pid FROM pg_stat_activity);")
|
105
|
+
end
|
86
106
|
end
|
87
107
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
108
|
+
require_relative "queue_classic/queue"
|
109
|
+
require_relative "queue_classic/worker"
|
110
|
+
require_relative "queue_classic/setup"
|
111
|
+
require_relative "queue_classic/railtie" if defined?(Rails)
|
@@ -30,10 +30,10 @@ module QC
|
|
30
30
|
|
31
31
|
def wait(time, *channels)
|
32
32
|
@mutex.synchronize do
|
33
|
-
listen_cmds = channels.map {|c| 'LISTEN "' + c + '"'}
|
33
|
+
listen_cmds = channels.map {|c| 'LISTEN "' + c.to_s + '"'}
|
34
34
|
@connection.exec(listen_cmds.join(';'))
|
35
35
|
wait_for_notify(time)
|
36
|
-
unlisten_cmds = channels.map {|c| 'UNLISTEN "' + c +'"'}
|
36
|
+
unlisten_cmds = channels.map {|c| 'UNLISTEN "' + c.to_s + '"'}
|
37
37
|
@connection.exec(unlisten_cmds.join(';'))
|
38
38
|
drain_notify
|
39
39
|
end
|
data/lib/queue_classic/queue.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
require 'queue_classic/conn_adapter'
|
1
|
+
require_relative 'conn_adapter'
|
3
2
|
require 'json'
|
3
|
+
require 'time'
|
4
4
|
|
5
5
|
module QC
|
6
6
|
# The queue class maps a queue abstraction onto a database table.
|
@@ -45,9 +45,17 @@ module QC
|
|
45
45
|
QC.log_yield(:measure => 'queue.lock') do
|
46
46
|
s = "SELECT * FROM lock_head($1, $2)"
|
47
47
|
if r = conn_adapter.execute(s, name, top_bound)
|
48
|
-
{
|
49
|
-
:
|
50
|
-
:
|
48
|
+
{}.tap do |job|
|
49
|
+
job[:id] = r["id"]
|
50
|
+
job[:q_name] = r["q_name"]
|
51
|
+
job[:method] = r["method"]
|
52
|
+
job[:args] = JSON.parse(r["args"])
|
53
|
+
if r["created_at"]
|
54
|
+
job[:created_at] = Time.parse(r["created_at"])
|
55
|
+
ttl = Integer((Time.now - job[:created_at]) * 1000)
|
56
|
+
QC.measure("time-to-lock=#{ttl}ms source=#{name}")
|
57
|
+
end
|
58
|
+
end
|
51
59
|
end
|
52
60
|
end
|
53
61
|
end
|
data/lib/queue_classic/setup.rb
CHANGED
@@ -4,19 +4,40 @@ module QC
|
|
4
4
|
SqlFunctions = File.join(Root, "/sql/ddl.sql")
|
5
5
|
CreateTable = File.join(Root, "/sql/create_table.sql")
|
6
6
|
DropSqlFunctions = File.join(Root, "/sql/drop_ddl.sql")
|
7
|
+
UpgradeTo_3_0_0 = File.join(Root, "/sql/update_to_3_0_0.sql")
|
8
|
+
DowngradeTo_3_0_0 = File.join(Root, "/sql/downgrade_from_3_0_0.sql")
|
7
9
|
|
8
|
-
def self.create(c=
|
10
|
+
def self.create(c = QC::default_conn_adapter.connection)
|
9
11
|
conn = QC::ConnAdapter.new(c)
|
10
12
|
conn.execute(File.read(CreateTable))
|
11
13
|
conn.execute(File.read(SqlFunctions))
|
12
14
|
conn.disconnect if c.nil? #Don't close a conn we didn't create.
|
13
15
|
end
|
14
16
|
|
15
|
-
def self.drop(c=
|
17
|
+
def self.drop(c = QC::default_conn_adapter.connection)
|
16
18
|
conn = QC::ConnAdapter.new(c)
|
17
19
|
conn.execute("DROP TABLE IF EXISTS queue_classic_jobs CASCADE")
|
18
20
|
conn.execute(File.read(DropSqlFunctions))
|
19
21
|
conn.disconnect if c.nil? #Don't close a conn we didn't create.
|
20
22
|
end
|
23
|
+
|
24
|
+
def self.update(c = QC::default_conn_adapter.connection)
|
25
|
+
conn = QC::ConnAdapter.new(c)
|
26
|
+
conn.execute(File.read(UpgradeTo_3_0_0))
|
27
|
+
conn.execute(File.read(DropSqlFunctions))
|
28
|
+
conn.execute(File.read(SqlFunctions))
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.update_to_3_0_0(c = QC::default_conn_adapter.connection)
|
32
|
+
conn = QC::ConnAdapter.new(c)
|
33
|
+
conn.execute(File.read(UpgradeTo_3_0_0))
|
34
|
+
conn.execute(File.read(DropSqlFunctions))
|
35
|
+
conn.execute(File.read(SqlFunctions))
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.downgrade_from_3_0_0(c = QC::default_conn_adapter.connection)
|
39
|
+
conn = QC::ConnAdapter.new(c)
|
40
|
+
conn.execute(File.read(DowngradeTo_3_0_0))
|
41
|
+
end
|
21
42
|
end
|
22
43
|
end
|
data/lib/queue_classic/tasks.rb
CHANGED
data/lib/queue_classic/worker.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'queue_classic/conn_adapter'
|
1
|
+
require_relative 'queue'
|
2
|
+
require_relative 'conn_adapter'
|
4
3
|
|
5
4
|
module QC
|
6
5
|
# A Worker object can process jobs from one or many queues.
|
@@ -19,7 +18,13 @@ module QC
|
|
19
18
|
def initialize(args={})
|
20
19
|
@fork_worker = args[:fork_worker] || QC::FORK_WORKER
|
21
20
|
@wait_interval = args[:wait_interval] || QC::WAIT_TIME
|
22
|
-
|
21
|
+
|
22
|
+
if args[:connection]
|
23
|
+
@conn_adapter = ConnAdapter.new(args[:connection])
|
24
|
+
elsif QC.has_connection?
|
25
|
+
@conn_adapter = QC.default_conn_adapter
|
26
|
+
end
|
27
|
+
|
23
28
|
@queues = setup_queues(@conn_adapter,
|
24
29
|
(args[:q_name] || QC::QUEUE),
|
25
30
|
(args[:q_names] || QC::QUEUES),
|
@@ -34,6 +39,8 @@ module QC
|
|
34
39
|
# The canonical example of starting a worker is as follows:
|
35
40
|
# QC::Worker.new.start
|
36
41
|
def start
|
42
|
+
QC.unlock_jobs_of_dead_workers
|
43
|
+
|
37
44
|
while @running
|
38
45
|
@fork_worker ? fork_and_work : work
|
39
46
|
end
|
@@ -97,6 +104,7 @@ module QC
|
|
97
104
|
# If the job is not finished and an INT signal is traped,
|
98
105
|
# this method will unlock the job in the queue.
|
99
106
|
def process(queue, job)
|
107
|
+
start = Time.now
|
100
108
|
finished = false
|
101
109
|
begin
|
102
110
|
call(job).tap do
|
@@ -110,6 +118,8 @@ module QC
|
|
110
118
|
if !finished
|
111
119
|
queue.unlock(job[:id])
|
112
120
|
end
|
121
|
+
ttp = Integer((Time.now - start) * 1000)
|
122
|
+
QC.measure("time-to-process=#{ttp} source=#{queue.name}")
|
113
123
|
end
|
114
124
|
end
|
115
125
|
|
@@ -126,7 +136,7 @@ module QC
|
|
126
136
|
# This method will be called when an exception
|
127
137
|
# is raised during the execution of the job.
|
128
138
|
def handle_failure(job,e)
|
129
|
-
|
139
|
+
$stderr.puts("count#qc.job-error=1 job=#{job} error=#{e.inspect}")
|
130
140
|
end
|
131
141
|
|
132
142
|
# This method should be overriden if
|
data/readme.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
# queue_classic
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/ryandotsmith/queue_classic.svg?branch=master)](https://travis-ci.org/ryandotsmith/queue_classic)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/ryandotsmith/queue_classic.png)](https://codeclimate.com/github/ryandotsmith/queue_classic)
|
5
|
+
|
3
6
|
Stable: [v2.2.3](https://github.com/ryandotsmith/queue_classic/tree/v2.2.3)
|
4
|
-
Latest: v3.0.
|
7
|
+
Latest: v3.0.0rc
|
5
8
|
|
6
9
|
queue_classic provides a simple interface to a PostgreSQL-backed message queue. queue_classic specializes in concurrent locking and minimizing database load while providing a simple, intuitive developer experience. queue_classic assumes that you are already using PostgreSQL in your production environment and that adding another dependency (e.g. redis, beanstalkd, 0mq) is undesirable.
|
7
10
|
|
@@ -19,7 +22,10 @@ Contents:
|
|
19
22
|
* [Documentation](http://rubydoc.info/gems/queue_classic/2.2.3/frames)
|
20
23
|
* [Usage](#usage)
|
21
24
|
* [Setup](#setup)
|
25
|
+
* [Upgrade from V2 to V3](#upgrade-from-v2-to-v3)
|
22
26
|
* [Configuration](#configuration)
|
27
|
+
* [JSON](#json)
|
28
|
+
* [Logging](#logging)
|
23
29
|
* [Support](#support)
|
24
30
|
* [Hacking](#hacking-on-queue_classic)
|
25
31
|
* [License](#license)
|
@@ -165,6 +171,25 @@ $ bundle exec rake qc:create
|
|
165
171
|
$ bundle exec rake qc:drop
|
166
172
|
```
|
167
173
|
|
174
|
+
## Upgrade from V2 to V3
|
175
|
+
If you are upgrading from a previous version of queue_classic, you might need some new database columns and/or functions. Luckily enough for you, it is easy to do so.
|
176
|
+
|
177
|
+
### Ruby on Rails
|
178
|
+
|
179
|
+
You just need to run those lines, which will copy the new required migrations:
|
180
|
+
|
181
|
+
```
|
182
|
+
rails generate queue_classic:install
|
183
|
+
rake db:migrate
|
184
|
+
```
|
185
|
+
### Rake Task
|
186
|
+
|
187
|
+
This rake task will get you covered:
|
188
|
+
```bash
|
189
|
+
# Updating the table and functions
|
190
|
+
$ bundle exec rake qc:update
|
191
|
+
```
|
192
|
+
|
168
193
|
## Configuration
|
169
194
|
|
170
195
|
All configuration takes place in the form of environment vars. See [queue_classic.rb](https://github.com/ryandotsmith/queue_classic/blob/master/lib/queue_classic.rb#L23-62) for a list of options.
|
@@ -179,8 +204,17 @@ alter table queue_classic_jobs alter column args type json using (args::json);
|
|
179
204
|
## Logging
|
180
205
|
|
181
206
|
By default queue_classic does not talk very much.
|
182
|
-
If you find yourself in a situation where you need to know what's happening inside QC,
|
183
|
-
|
207
|
+
If you find yourself in a situation where you need to know what's happening inside QC, there are two different kind of logging you can enable: DEBUG and MEASURE.
|
208
|
+
|
209
|
+
### Measure
|
210
|
+
This will output the time to process and that kind of thing. To enable it, set the `QC_MEASURE`:
|
211
|
+
|
212
|
+
```
|
213
|
+
export QC_MEASURE="true"
|
214
|
+
```
|
215
|
+
|
216
|
+
### Debug
|
217
|
+
You can enable the debug output by setting the `DEBUG` environment variable:
|
184
218
|
|
185
219
|
```
|
186
220
|
export DEBUG="true"
|
@@ -201,7 +235,8 @@ https://groups.google.com/d/forum/queue_classic
|
|
201
235
|
|
202
236
|
## Hacking on queue_classic
|
203
237
|
|
204
|
-
[![Build Status](https://
|
238
|
+
[![Build Status](https://travis-ci.org/ryandotsmith/queue_classic.svg?branch=master)](https://travis-ci.org/ryandotsmith/queue_classic)
|
239
|
+
[![Code Climate](https://codeclimate.com/github/ryandotsmith/queue_classic.png)](https://codeclimate.com/github/ryandotsmith/queue_classic)
|
205
240
|
|
206
241
|
### Dependencies
|
207
242
|
|
data/sql/create_table.sql
CHANGED
@@ -5,7 +5,9 @@ CREATE TABLE queue_classic_jobs (
|
|
5
5
|
q_name text not null check (length(q_name) > 0),
|
6
6
|
method text not null check (length(method) > 0),
|
7
7
|
args text not null,
|
8
|
-
locked_at timestamptz
|
8
|
+
locked_at timestamptz,
|
9
|
+
locked_by integer,
|
10
|
+
created_at timestamptz default now()
|
9
11
|
);
|
10
12
|
|
11
13
|
-- If json type is available, use it for the args column.
|
data/sql/ddl.sql
CHANGED
@@ -15,7 +15,9 @@ BEGIN
|
|
15
15
|
-- for more workers. Would love to see some optimization here...
|
16
16
|
|
17
17
|
EXECUTE 'SELECT count(*) FROM '
|
18
|
-
|| '(SELECT * FROM queue_classic_jobs
|
18
|
+
|| '(SELECT * FROM queue_classic_jobs '
|
19
|
+
|| ' WHERE locked_at IS NULL'
|
20
|
+
|| ' AND q_name = '
|
19
21
|
|| quote_literal(q_name)
|
20
22
|
|| ' LIMIT '
|
21
23
|
|| quote_literal(top_boundary)
|
@@ -48,7 +50,8 @@ BEGIN
|
|
48
50
|
END LOOP;
|
49
51
|
|
50
52
|
RETURN QUERY EXECUTE 'UPDATE queue_classic_jobs '
|
51
|
-
|| ' SET locked_at = (CURRENT_TIMESTAMP)'
|
53
|
+
|| ' SET locked_at = (CURRENT_TIMESTAMP),'
|
54
|
+
|| ' locked_by = (select pg_backend_pid())'
|
52
55
|
|| ' WHERE id = $1'
|
53
56
|
|| ' AND locked_at is NULL'
|
54
57
|
|| ' RETURNING *'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
DO $$DECLARE r record;
|
2
|
+
BEGIN
|
3
|
+
BEGIN
|
4
|
+
ALTER TABLE queue_classic_jobs ADD COLUMN created_at timestamptz default now();
|
5
|
+
EXCEPTION
|
6
|
+
WHEN duplicate_column THEN RAISE NOTICE 'column created_at already exists in queue_classic_jobs.';
|
7
|
+
END;
|
8
|
+
END$$;
|
9
|
+
|
10
|
+
DO $$DECLARE r record;
|
11
|
+
BEGIN
|
12
|
+
BEGIN
|
13
|
+
ALTER TABLE queue_classic_jobs ADD COLUMN locked_by integer;
|
14
|
+
EXCEPTION
|
15
|
+
WHEN duplicate_column THEN RAISE NOTICE 'column locked_by already exists in queue_classic_jobs.';
|
16
|
+
END;
|
17
|
+
END$$;
|
data/test/helper.rb
CHANGED
@@ -26,6 +26,15 @@ class QCTest < Minitest::Test
|
|
26
26
|
c.disconnect
|
27
27
|
end
|
28
28
|
|
29
|
+
def capture_stderr_output
|
30
|
+
original_stderr = $stderr
|
31
|
+
$stderr = StringIO.new
|
32
|
+
yield
|
33
|
+
$stderr.string
|
34
|
+
ensure
|
35
|
+
$stderr = original_stderr
|
36
|
+
end
|
37
|
+
|
29
38
|
def capture_debug_output
|
30
39
|
original_debug = ENV['DEBUG']
|
31
40
|
original_stdout = $stdout
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path("../../helper.rb", __FILE__)
|
2
|
+
|
3
|
+
class QueueClassicTest < QCTest
|
4
|
+
def test_default_conn_adapter_default_value
|
5
|
+
assert(QC.default_conn_adapter.is_a?(QC::ConnAdapter))
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_default_conn_adapter=
|
9
|
+
connection = QC::ConnAdapter.new
|
10
|
+
QC.default_conn_adapter = connection
|
11
|
+
assert_equal(QC.default_conn_adapter, connection)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_unlock_jobs_of_dead_workers
|
15
|
+
# Insert a locked job
|
16
|
+
adapter = QC::ConnAdapter.new
|
17
|
+
query = "INSERT INTO #{QC::TABLE_NAME} (q_name, method, args, locked_by, locked_at) VALUES ('whatever', 'Kernel.puts', '[\"ok?\"]', 0, (CURRENT_TIMESTAMP))"
|
18
|
+
adapter.execute(query)
|
19
|
+
|
20
|
+
# We should have no unlocked jobs
|
21
|
+
query_locked_jobs = "SELECT * FROM #{QC::TABLE_NAME} WHERE locked_at IS NULL"
|
22
|
+
res = adapter.connection.exec(query_locked_jobs)
|
23
|
+
assert_equal(0, res.count)
|
24
|
+
|
25
|
+
# Unlock the job
|
26
|
+
QC.unlock_jobs_of_dead_workers
|
27
|
+
|
28
|
+
# We should have an unlocked job now
|
29
|
+
res = adapter.connection.exec(query_locked_jobs)
|
30
|
+
assert_equal(1, res.count)
|
31
|
+
end
|
32
|
+
end
|
data/test/queue_test.rb
CHANGED
@@ -13,12 +13,14 @@ class QueueTest < QCTest
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_lock
|
16
|
-
QC.
|
17
|
-
|
18
|
-
|
19
|
-
# number.
|
20
|
-
|
21
|
-
assert_equal(
|
16
|
+
queue = QC::Queue.new("queue_classic_jobs")
|
17
|
+
queue.enqueue("Klass.method")
|
18
|
+
job = queue.lock
|
19
|
+
# See helper.rb for more information about the large initial id number.
|
20
|
+
assert_equal((2**34).to_s, job[:id])
|
21
|
+
assert_equal("queue_classic_jobs", job[:q_name])
|
22
|
+
assert_equal("Klass.method", job[:method])
|
23
|
+
assert_equal([], job[:args])
|
22
24
|
end
|
23
25
|
|
24
26
|
def test_lock_when_empty
|
data/test/worker_test.rb
CHANGED
@@ -45,12 +45,11 @@ class WorkerTest < QCTest
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_failed_job_is_logged
|
48
|
-
output =
|
48
|
+
output = capture_stderr_output do
|
49
49
|
QC.enqueue("TestObject.not_a_method")
|
50
50
|
TestWorker.new.work
|
51
51
|
end
|
52
|
-
|
53
|
-
assert_match(expected_output, output, "=== debug output ===\n #{output}")
|
52
|
+
assert(output.include?("#<NoMethodError: undefined method `not_a_method'"))
|
54
53
|
end
|
55
54
|
|
56
55
|
def test_log_yield
|
@@ -175,5 +174,4 @@ class WorkerTest < QCTest
|
|
175
174
|
assert_equal(42, r)
|
176
175
|
assert_equal(0, worker.failed_count)
|
177
176
|
end
|
178
|
-
|
179
177
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: queue_classic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Smith (♠ ace hacker)
|
@@ -14,14 +14,14 @@ dependencies:
|
|
14
14
|
name: pg
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.17.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.17.0
|
27
27
|
description: queue_classic is a queueing library for Ruby apps. (Rails, Sinatra, Etc...)
|
@@ -32,21 +32,25 @@ executables: []
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
-
- readme.md
|
36
|
-
- sql/create_table.sql
|
37
|
-
- sql/ddl.sql
|
38
|
-
- sql/drop_ddl.sql
|
39
35
|
- lib/generators/queue_classic/install_generator.rb
|
40
36
|
- lib/generators/queue_classic/templates/add_queue_classic.rb
|
37
|
+
- lib/generators/queue_classic/templates/update_queue_classic_3_0_0.rb
|
38
|
+
- lib/queue_classic.rb
|
41
39
|
- lib/queue_classic/conn_adapter.rb
|
42
40
|
- lib/queue_classic/queue.rb
|
43
41
|
- lib/queue_classic/railtie.rb
|
44
42
|
- lib/queue_classic/setup.rb
|
45
43
|
- lib/queue_classic/tasks.rb
|
46
44
|
- lib/queue_classic/worker.rb
|
47
|
-
-
|
45
|
+
- readme.md
|
46
|
+
- sql/create_table.sql
|
47
|
+
- sql/ddl.sql
|
48
|
+
- sql/downgrade_from_3_0_0.sql
|
49
|
+
- sql/drop_ddl.sql
|
50
|
+
- sql/update_to_3_0_0.sql
|
48
51
|
- test/benchmark_test.rb
|
49
52
|
- test/helper.rb
|
53
|
+
- test/lib/queue_classic_test.rb
|
50
54
|
- test/queue_test.rb
|
51
55
|
- test/worker_test.rb
|
52
56
|
homepage: http://github.com/ryandotsmith/queue_classic
|
@@ -59,21 +63,22 @@ require_paths:
|
|
59
63
|
- lib
|
60
64
|
required_ruby_version: !ruby/object:Gem::Requirement
|
61
65
|
requirements:
|
62
|
-
- -
|
66
|
+
- - ">="
|
63
67
|
- !ruby/object:Gem::Version
|
64
68
|
version: '0'
|
65
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
70
|
requirements:
|
67
|
-
- -
|
71
|
+
- - ">="
|
68
72
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
73
|
+
version: '0'
|
70
74
|
requirements: []
|
71
75
|
rubyforge_project:
|
72
|
-
rubygems_version: 2.
|
76
|
+
rubygems_version: 2.2.2
|
73
77
|
signing_key:
|
74
78
|
specification_version: 4
|
75
79
|
summary: Simple, efficient worker queue for Ruby & PostgreSQL.
|
76
80
|
test_files:
|
77
81
|
- test/benchmark_test.rb
|
82
|
+
- test/lib/queue_classic_test.rb
|
78
83
|
- test/queue_test.rb
|
79
84
|
- test/worker_test.rb
|