queue_classic 2.1.1 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/queue_classic.rb +5 -0
- data/lib/queue_classic/conn.rb +1 -1
- data/lib/queue_classic/worker.rb +17 -11
- data/readme.md +4 -10
- data/sql/create_table.sql +1 -1
- data/sql/ddl.sql +1 -1
- data/test/helper.rb +26 -0
- data/test/queue_test.rb +8 -1
- metadata +1 -1
data/lib/queue_classic.rb
CHANGED
@@ -61,6 +61,11 @@ module QC
|
|
61
61
|
default_queue.send(sym, *args, &block)
|
62
62
|
end
|
63
63
|
|
64
|
+
# Ensure QC.respond_to?(:enqueue) equals true (ruby 1.9 only)
|
65
|
+
def self.respond_to_missing?(method_name, include_private = false)
|
66
|
+
default_queue.respond_to?(method_name)
|
67
|
+
end
|
68
|
+
|
64
69
|
def self.default_queue
|
65
70
|
@default_queue ||= begin
|
66
71
|
Queue.new(QUEUE)
|
data/lib/queue_classic/conn.rb
CHANGED
@@ -86,7 +86,7 @@ module QC
|
|
86
86
|
def connect
|
87
87
|
log(:at => "establish_conn")
|
88
88
|
conn = PGconn.connect(
|
89
|
-
db_url.host,
|
89
|
+
db_url.host.gsub(/%2F/i, '/'), # host or percent-encoded socket path
|
90
90
|
db_url.port || 5432,
|
91
91
|
nil, '', #opts, tty
|
92
92
|
db_url.path.gsub("/",""), # database name
|
data/lib/queue_classic/worker.rb
CHANGED
@@ -41,20 +41,11 @@ module QC
|
|
41
41
|
Process.wait(@cpid)
|
42
42
|
end
|
43
43
|
|
44
|
-
# This method will lock a job &
|
45
|
-
# Also, this method will make the best attempt to delete the job
|
46
|
-
# from the queue before returning.
|
44
|
+
# This method will lock a job & process the job.
|
47
45
|
def work
|
48
46
|
if job = lock_job
|
49
47
|
QC.log_yield(:at => "work", :job => job[:id]) do
|
50
|
-
|
51
|
-
call(job)
|
52
|
-
rescue => e
|
53
|
-
handle_failure(job, e)
|
54
|
-
ensure
|
55
|
-
@queue.delete(job[:id])
|
56
|
-
log(:at => "delete_job", :job => job[:id])
|
57
|
-
end
|
48
|
+
process(job)
|
58
49
|
end
|
59
50
|
end
|
60
51
|
end
|
@@ -90,6 +81,21 @@ module QC
|
|
90
81
|
job
|
91
82
|
end
|
92
83
|
|
84
|
+
# A job is processed by evaluating the target code.
|
85
|
+
# Errors are delegated to the handle_failure method.
|
86
|
+
# Also, this method will make the best attempt to delete the job
|
87
|
+
# from the queue before returning.
|
88
|
+
def process(job)
|
89
|
+
begin
|
90
|
+
call(job)
|
91
|
+
rescue => e
|
92
|
+
handle_failure(job, e)
|
93
|
+
ensure
|
94
|
+
@queue.delete(job[:id])
|
95
|
+
log(:at => "delete_job", :job => job[:id])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
93
99
|
# Each job includes a method column. We will use ruby's eval
|
94
100
|
# to grab the ruby object from memory. We send the method to
|
95
101
|
# the object and pass the args.
|
data/readme.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# queue_classic
|
2
2
|
|
3
|
-
v2.1.
|
3
|
+
v2.1.2
|
4
4
|
|
5
5
|
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.
|
6
6
|
|
@@ -47,7 +47,7 @@ QC.enqueue("Kernel.puts", {"hello" => "world"})
|
|
47
47
|
QC.enqueue("Kernel.puts", ["hello", "world"])
|
48
48
|
|
49
49
|
# This method uses a non-default queue.
|
50
|
-
p_queue = QC::Queue.new(
|
50
|
+
p_queue = QC::Queue.new("priority_queue")
|
51
51
|
p_queue.enqueue("Kernel.puts", ["hello", "world"])
|
52
52
|
```
|
53
53
|
|
@@ -83,7 +83,7 @@ $ bundle exec rake qc:work
|
|
83
83
|
Setup a worker to work a non-default queue.
|
84
84
|
|
85
85
|
```bash
|
86
|
-
$ QUEUE="
|
86
|
+
$ QUEUE="priority_queue" bundle exec rake qc:work
|
87
87
|
```
|
88
88
|
|
89
89
|
#### Custom Worker
|
@@ -110,13 +110,7 @@ worker = MyWorker.new(max_attempts: 10, listening_worker: true)
|
|
110
110
|
loop do
|
111
111
|
job = worker.lock_job
|
112
112
|
Thread.new do
|
113
|
-
|
114
|
-
Timeout::timeout(5) {worker.call(job)}
|
115
|
-
rescue => e
|
116
|
-
handle_failure(job, e)
|
117
|
-
ensure
|
118
|
-
worker.delete(job[:id])
|
119
|
-
end
|
113
|
+
Timeout::timeout(5) { worker.process(job) }
|
120
114
|
end
|
121
115
|
end
|
122
116
|
```
|
data/sql/create_table.sql
CHANGED
data/sql/ddl.sql
CHANGED
data/test/helper.rb
CHANGED
@@ -21,6 +21,32 @@ class QCTest < MiniTest::Unit::TestCase
|
|
21
21
|
QC::Conn.execute("SET client_min_messages TO 'warning'")
|
22
22
|
QC::Setup.drop
|
23
23
|
QC::Setup.create
|
24
|
+
QC::Conn.execute(<<EOS)
|
25
|
+
DO $$
|
26
|
+
-- Set initial sequence to a large number to test the entire toolchain
|
27
|
+
-- works on integers with higher bits set.
|
28
|
+
DECLARE
|
29
|
+
quoted_name text;
|
30
|
+
quoted_size text;
|
31
|
+
BEGIN
|
32
|
+
-- Find the name of the relevant sequence.
|
33
|
+
--
|
34
|
+
-- pg_get_serial_sequence quotes identifiers as part of its
|
35
|
+
-- behavior.
|
36
|
+
SELECT name
|
37
|
+
INTO STRICT quoted_name
|
38
|
+
FROM pg_get_serial_sequence('queue_classic_jobs', 'id') AS name;
|
39
|
+
|
40
|
+
-- Don't quote, because ALTER SEQUENCE RESTART doesn't like
|
41
|
+
-- general literals, only unquoted numeric literals.
|
42
|
+
SELECT pow(2, 34)::text AS size
|
43
|
+
INTO STRICT quoted_size;
|
44
|
+
|
45
|
+
EXECUTE 'ALTER SEQUENCE ' || quoted_name ||
|
46
|
+
' RESTART ' || quoted_size || ';';
|
47
|
+
END;
|
48
|
+
$$;
|
49
|
+
EOS
|
24
50
|
QC::Conn.disconnect
|
25
51
|
end
|
26
52
|
|
data/test/queue_test.rb
CHANGED
@@ -6,9 +6,16 @@ class QueueTest < QCTest
|
|
6
6
|
QC.enqueue("Klass.method")
|
7
7
|
end
|
8
8
|
|
9
|
+
def test_respond_to
|
10
|
+
assert_equal(true, QC.respond_to?(:enqueue))
|
11
|
+
end
|
12
|
+
|
9
13
|
def test_lock
|
10
14
|
QC.enqueue("Klass.method")
|
11
|
-
|
15
|
+
|
16
|
+
# See helper.rb for more information about the large initial id
|
17
|
+
# number.
|
18
|
+
expected = {:id=>(2**34).to_s, :method=>"Klass.method", :args=>[]}
|
12
19
|
assert_equal(expected, QC.lock)
|
13
20
|
end
|
14
21
|
|