postqueue 0.2.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +103 -49
- data/lib/postqueue/item/enqueue.rb +33 -0
- data/lib/postqueue/item/inserter.rb +29 -0
- data/lib/postqueue/item.rb +14 -0
- data/lib/postqueue/logger.rb +9 -0
- data/lib/postqueue/queue/callback.rb +60 -0
- data/lib/postqueue/queue/logging.rb +22 -0
- data/lib/postqueue/queue/processing.rb +57 -0
- data/lib/postqueue/{base → queue}/select_and_lock.rb +24 -9
- data/lib/postqueue/queue.rb +61 -0
- data/lib/postqueue/version.rb +1 -1
- data/lib/postqueue.rb +18 -4
- data/lib/tracker/advisory_lock.rb +39 -0
- data/lib/tracker/migration.rb +23 -0
- data/lib/tracker/registry.rb +45 -0
- data/lib/tracker/tracker.sql +231 -0
- data/lib/tracker.rb +125 -0
- data/spec/postqueue/concurrency_spec.rb +77 -0
- data/spec/postqueue/enqueue_spec.rb +3 -37
- data/spec/postqueue/idempotent_ops_spec.rb +66 -0
- data/spec/postqueue/process_errors_spec.rb +27 -40
- data/spec/postqueue/process_spec.rb +37 -28
- data/spec/postqueue/syncmode_spec.rb +38 -0
- data/spec/postqueue/wildcard_spec.rb +31 -0
- data/spec/spec_helper.rb +1 -12
- data/spec/support/configure_active_record.rb +7 -13
- data/spec/support/connect_active_record.rb +5 -0
- metadata +20 -7
- data/lib/postqueue/base/callback.rb +0 -23
- data/lib/postqueue/base/enqueue.rb +0 -31
- data/lib/postqueue/base/processing.rb +0 -57
- data/lib/postqueue/base.rb +0 -41
@@ -1,68 +1,55 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "
|
4
|
-
let(:queue)
|
3
|
+
describe "error handling" do
|
4
|
+
let(:queue) do
|
5
|
+
Postqueue.new do |queue|
|
6
|
+
queue.batch_sizes["batchable"] = 10
|
7
|
+
queue.batch_sizes["other-batchable"] = 10
|
8
|
+
end
|
9
|
+
end
|
5
10
|
|
6
|
-
|
11
|
+
let(:items) { queue.item_class.all }
|
12
|
+
let(:item) { queue.item_class.first }
|
7
13
|
|
8
|
-
|
9
|
-
queue.enqueue op: "mytype", entity_id: 12
|
10
|
-
end
|
14
|
+
class E < RuntimeError; end
|
11
15
|
|
12
|
-
context "
|
16
|
+
context "when handler raises an exception" do
|
13
17
|
before do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
it "reraises the exception" do
|
18
|
-
# checked in before block
|
18
|
+
queue.on "mytype" do raise E end
|
19
|
+
queue.enqueue op: "mytype", entity_id: 12
|
19
20
|
end
|
20
21
|
|
21
|
-
it "keeps the item in the queue" do
|
22
|
+
it "reraises the exception, keeps the item in the queue and increments the failed_attempt count" do
|
23
|
+
expect { queue.process_one }.to raise_error(E)
|
22
24
|
expect(items.map(&:entity_id)).to contain_exactly(12)
|
23
|
-
end
|
24
|
-
|
25
|
-
it "increments the failed_attempt count" do
|
26
25
|
expect(items.map(&:failed_attempts)).to contain_exactly(1)
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
context "
|
29
|
+
context "when no handler can be found" do
|
31
30
|
before do
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
it "returns false" do
|
36
|
-
expect(@result).to be false
|
37
|
-
end
|
38
|
-
|
39
|
-
it "keeps the item in the queue" do
|
40
|
-
expect(items.map(&:entity_id)).to contain_exactly(12)
|
31
|
+
queue.enqueue op: "mytype", entity_id: 12
|
41
32
|
end
|
42
33
|
|
43
|
-
it "
|
44
|
-
expect
|
34
|
+
it "raises a MissingHandler exception" do
|
35
|
+
expect { queue.process_one }.to raise_error(::Postqueue::MissingHandler)
|
45
36
|
end
|
46
37
|
end
|
47
38
|
|
48
39
|
context "failed_attempts reached MAX_ATTEMPTS" do
|
49
40
|
before do
|
50
|
-
expect(
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
@result = queue.process_one do
|
55
|
-
@called_block += 1
|
56
|
-
false
|
57
|
-
end
|
41
|
+
expect(queue.max_attemps).to be >= 3
|
42
|
+
queue.enqueue op: "mytype", entity_id: 12
|
43
|
+
items.update_all(failed_attempts: queue.max_attemps)
|
44
|
+
queue.process_one
|
58
45
|
end
|
59
46
|
|
60
47
|
it "does not call the block" do
|
61
|
-
expect
|
48
|
+
expect { queue.process_one }.not_to raise_error
|
62
49
|
end
|
63
50
|
|
64
|
-
it "returns
|
65
|
-
expect(
|
51
|
+
it "returns 0" do
|
52
|
+
expect(queue.process_one).to eq(0)
|
66
53
|
end
|
67
54
|
|
68
55
|
it "does not remove the item" do
|
@@ -70,7 +57,7 @@ describe "::queue.process_one" do
|
|
70
57
|
end
|
71
58
|
|
72
59
|
it "does not increment the failed_attempts count" do
|
73
|
-
expect(items.first.failed_attempts).to eq(
|
60
|
+
expect(items.first.failed_attempts).to eq(queue.max_attemps)
|
74
61
|
end
|
75
62
|
end
|
76
63
|
end
|
@@ -1,14 +1,23 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
describe "processing" do
|
4
|
+
let(:processed_events) do
|
5
|
+
@processed_events ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:queue) do
|
9
|
+
Postqueue.new do |queue|
|
10
|
+
queue.batch_sizes["batchable"] = 10
|
11
|
+
queue.batch_sizes["other-batchable"] = 10
|
12
|
+
|
13
|
+
queue.on '*' do |op, entity_ids|
|
14
|
+
processed_events << [ op, entity_ids ]
|
15
|
+
end
|
8
16
|
end
|
9
17
|
end
|
10
18
|
|
11
|
-
let(:
|
19
|
+
let(:items) { queue.item_class.all }
|
20
|
+
let(:item) { queue.item_class.first }
|
12
21
|
|
13
22
|
describe "basics" do
|
14
23
|
before do
|
@@ -19,7 +28,7 @@ describe "::queue.process" do
|
|
19
28
|
|
20
29
|
it "processes the first entry" do
|
21
30
|
r = queue.process_one
|
22
|
-
expect(r).to eq(
|
31
|
+
expect(r).to eq(1)
|
23
32
|
expect(items.map(&:entity_id)).to contain_exactly(13, 14)
|
24
33
|
end
|
25
34
|
|
@@ -27,53 +36,53 @@ describe "::queue.process" do
|
|
27
36
|
queue.enqueue(op: "otherop", entity_id: 112)
|
28
37
|
|
29
38
|
r = queue.process_one(op: "otherop")
|
30
|
-
expect(r).to eq(
|
39
|
+
expect(r).to eq(1)
|
31
40
|
expect(items.map(&:entity_id)).to contain_exactly(12, 13, 14)
|
32
41
|
end
|
33
42
|
|
34
|
-
it "yields a block and returns
|
43
|
+
it "yields a block and returns the processed entries" do
|
35
44
|
queue.enqueue op: "otherop", entity_id: 112
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
45
|
+
called = false
|
46
|
+
queue.process_one(op: "otherop")
|
47
|
+
|
48
|
+
op, ids = processed_events.first
|
49
|
+
expect(op).to eq("otherop")
|
50
|
+
expect(ids).to eq([112])
|
41
51
|
|
42
|
-
expect(r).to eq("yihaa")
|
43
52
|
expect(items.map(&:entity_id)).to contain_exactly(12, 13, 14)
|
44
53
|
end
|
45
54
|
end
|
46
55
|
|
47
56
|
context "when having entries with different entity_type and op" do
|
48
57
|
before do
|
49
|
-
queue.enqueue op: "
|
50
|
-
queue.enqueue op: "
|
51
|
-
queue.enqueue op: "
|
52
|
-
queue.enqueue op: "
|
53
|
-
queue.enqueue op: "
|
58
|
+
queue.enqueue op: "batchable", entity_id: 12
|
59
|
+
queue.enqueue op: "batchable", entity_id: 13
|
60
|
+
queue.enqueue op: "other-batchable", entity_id: 14
|
61
|
+
queue.enqueue op: "batchable", entity_id: 15
|
62
|
+
queue.enqueue op: "other-batchable", entity_id: 16
|
54
63
|
end
|
55
64
|
|
56
|
-
it "processes one
|
65
|
+
it "processes one matching entry with batch_size 1" do
|
57
66
|
r = queue.process batch_size: 1
|
58
|
-
expect(r).to eq(
|
67
|
+
expect(r).to eq(1)
|
59
68
|
expect(items.map(&:entity_id)).to contain_exactly(13, 14, 15, 16)
|
60
69
|
end
|
61
70
|
|
62
|
-
it "processes two entries" do
|
71
|
+
it "processes two matching entries" do
|
63
72
|
r = queue.process batch_size: 2
|
64
|
-
expect(r).to eq(
|
73
|
+
expect(r).to eq(2)
|
65
74
|
expect(items.map(&:entity_id)).to contain_exactly(14, 15, 16)
|
66
75
|
end
|
67
76
|
|
68
|
-
it "processes
|
77
|
+
it "processes all matching entries" do
|
69
78
|
r = queue.process
|
70
|
-
expect(r).to eq(
|
79
|
+
expect(r).to eq(3)
|
71
80
|
expect(items.map(&:entity_id)).to contain_exactly(14, 16)
|
72
81
|
end
|
73
82
|
|
74
83
|
it "honors search conditions" do
|
75
|
-
r = queue.process(op: "
|
76
|
-
expect(r).to eq(
|
84
|
+
r = queue.process(op: "other-batchable")
|
85
|
+
expect(r).to eq(2)
|
77
86
|
expect(items.map(&:entity_id)).to contain_exactly(12, 13, 15)
|
78
87
|
end
|
79
88
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "sync_processing" do
|
4
|
+
let(:callback_invocations) { @callback_invocations ||= [] }
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
Postqueue.async_processing = false
|
8
|
+
end
|
9
|
+
|
10
|
+
after :all do
|
11
|
+
Postqueue.async_processing = true
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:queue) do
|
15
|
+
Postqueue.new do |queue|
|
16
|
+
queue.on "op" do |op, entity_ids|
|
17
|
+
callback_invocations << [ op, entity_ids ]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:items) { queue.item_class.all }
|
23
|
+
let(:item) { queue.item_class.first }
|
24
|
+
|
25
|
+
context "when enqueuing in sync mode" do
|
26
|
+
before do
|
27
|
+
queue.enqueue op: "op", entity_id: 12
|
28
|
+
end
|
29
|
+
|
30
|
+
it "processed the items" do
|
31
|
+
expect(callback_invocations.length).to eq(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "removed all items" do
|
35
|
+
expect(items.count).to eq(0)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "wildcard processing" do
|
4
|
+
let(:callback_invocations) { @callback_invocations ||= [] }
|
5
|
+
|
6
|
+
let(:queue) do
|
7
|
+
Postqueue.new do |queue|
|
8
|
+
queue.on "*" do |op, entity_ids|
|
9
|
+
callback_invocations << [ op, entity_ids ]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:items) { queue.item_class.all }
|
15
|
+
let(:item) { queue.item_class.first }
|
16
|
+
|
17
|
+
context "when enqueuing in sync mode" do
|
18
|
+
before do
|
19
|
+
queue.enqueue op: "op", entity_id: 12
|
20
|
+
queue.process
|
21
|
+
end
|
22
|
+
|
23
|
+
it "processed the items" do
|
24
|
+
expect(callback_invocations.length).to eq(1)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "removed all items" do
|
28
|
+
expect(items.count).to eq(0)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
path = File.expand_path("../../mpx/lib", __FILE__)
|
2
|
-
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
3
|
-
|
4
1
|
ENV["RACK_ENV"] = "test"
|
5
2
|
|
6
3
|
require "rspec"
|
@@ -14,15 +11,7 @@ end
|
|
14
11
|
require "postqueue"
|
15
12
|
require "./spec/support/configure_active_record"
|
16
13
|
|
17
|
-
|
18
|
-
def self.logger
|
19
|
-
@logger ||= Logger.new(File.open("log/test.log", "a"))
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def items
|
24
|
-
Postqueue::Item.all
|
25
|
-
end
|
14
|
+
Postqueue.logger = Logger.new(File.open("log/test.log", "a"))
|
26
15
|
|
27
16
|
RSpec.configure do |config|
|
28
17
|
config.run_all_when_everything_filtered = true
|
@@ -1,23 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
$LOAD_PATH << File.dirname(__FILE__)
|
4
|
-
|
5
|
-
ActiveRecord::Base.establish_connection(adapter: "postgresql",
|
6
|
-
database: "postqueue_test",
|
7
|
-
username: "postqueue",
|
8
|
-
password: "postqueue")
|
9
|
-
|
10
|
-
# require_relative "schema.rb"
|
11
|
-
# require_relative "models.rb"
|
1
|
+
require_relative "./connect_active_record"
|
12
2
|
|
13
3
|
Postqueue.unmigrate!
|
14
4
|
Postqueue.migrate!
|
15
5
|
|
16
6
|
RSpec.configure do |config|
|
17
7
|
config.around(:each) do |example|
|
18
|
-
|
8
|
+
if example.metadata[:transactions] == false
|
19
9
|
example.run
|
20
|
-
|
10
|
+
else
|
11
|
+
ActiveRecord::Base.connection.transaction do
|
12
|
+
example.run
|
13
|
+
raise ActiveRecord::Rollback, "Clean up"
|
14
|
+
end
|
21
15
|
end
|
22
16
|
end
|
23
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -145,19 +145,32 @@ extra_rdoc_files: []
|
|
145
145
|
files:
|
146
146
|
- README.md
|
147
147
|
- lib/postqueue.rb
|
148
|
-
- lib/postqueue/base.rb
|
149
|
-
- lib/postqueue/base/callback.rb
|
150
|
-
- lib/postqueue/base/enqueue.rb
|
151
|
-
- lib/postqueue/base/processing.rb
|
152
|
-
- lib/postqueue/base/select_and_lock.rb
|
153
148
|
- lib/postqueue/item.rb
|
149
|
+
- lib/postqueue/item/enqueue.rb
|
150
|
+
- lib/postqueue/item/inserter.rb
|
151
|
+
- lib/postqueue/logger.rb
|
152
|
+
- lib/postqueue/queue.rb
|
153
|
+
- lib/postqueue/queue/callback.rb
|
154
|
+
- lib/postqueue/queue/logging.rb
|
155
|
+
- lib/postqueue/queue/processing.rb
|
156
|
+
- lib/postqueue/queue/select_and_lock.rb
|
154
157
|
- lib/postqueue/version.rb
|
158
|
+
- lib/tracker.rb
|
159
|
+
- lib/tracker/advisory_lock.rb
|
160
|
+
- lib/tracker/migration.rb
|
161
|
+
- lib/tracker/registry.rb
|
162
|
+
- lib/tracker/tracker.sql
|
163
|
+
- spec/postqueue/concurrency_spec.rb
|
155
164
|
- spec/postqueue/enqueue_spec.rb
|
165
|
+
- spec/postqueue/idempotent_ops_spec.rb
|
156
166
|
- spec/postqueue/postqueue_spec.rb
|
157
167
|
- spec/postqueue/process_errors_spec.rb
|
158
168
|
- spec/postqueue/process_spec.rb
|
169
|
+
- spec/postqueue/syncmode_spec.rb
|
170
|
+
- spec/postqueue/wildcard_spec.rb
|
159
171
|
- spec/spec_helper.rb
|
160
172
|
- spec/support/configure_active_record.rb
|
173
|
+
- spec/support/connect_active_record.rb
|
161
174
|
homepage: https://github.com/radiospiel/postqueue
|
162
175
|
licenses:
|
163
176
|
- MIT
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Postqueue
|
2
|
-
class Base
|
3
|
-
def run_callback(op:, entity_ids:, &_block)
|
4
|
-
queue_times = item_class.find_by_sql <<-SQL
|
5
|
-
SELECT extract('epoch' from AVG(now() - created_at)) AS avg,
|
6
|
-
extract('epoch' from MAX(now() - created_at)) AS max
|
7
|
-
FROM #{item_class.table_name} WHERE entity_id IN (#{entity_ids.join(',')})
|
8
|
-
SQL
|
9
|
-
queue_time = queue_times.first
|
10
|
-
|
11
|
-
# run callback.
|
12
|
-
result = [ op, entity_ids ]
|
13
|
-
|
14
|
-
total_processing_time = Benchmark.realtime do
|
15
|
-
result = yield(*result) if block_given?
|
16
|
-
end
|
17
|
-
|
18
|
-
timing = Timing.new(queue_time.avg, queue_time.max, total_processing_time, total_processing_time / entity_ids.length)
|
19
|
-
|
20
|
-
[ result, timing ]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Postqueue
|
2
|
-
class Base
|
3
|
-
# Enqueues an queue item. If the operation is duplicate, and an entry with
|
4
|
-
# the same combination of op and entity_id exists already, no new entry will
|
5
|
-
# be added to the queue.
|
6
|
-
#
|
7
|
-
# [TODO] An optimized code path, talking directly to PG, might be faster by a factor of 4 or so.
|
8
|
-
def enqueue(op:, entity_id:, duplicate: true)
|
9
|
-
if entity_id.is_a?(Array)
|
10
|
-
enqueue_many(op: op, entity_ids: entity_id, duplicate: duplicate)
|
11
|
-
return
|
12
|
-
end
|
13
|
-
|
14
|
-
if !duplicate && item_class.where(op: op, entity_id: entity_id).present?
|
15
|
-
return
|
16
|
-
end
|
17
|
-
|
18
|
-
item_class.create!(op: op, entity_id: entity_id)
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def enqueue_many(op:, entity_ids:, duplicate:) #:nodoc:
|
24
|
-
item_class.transaction do
|
25
|
-
entity_ids.each do |entity_id|
|
26
|
-
enqueue(op: op, entity_id: entity_id, duplicate: duplicate)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
module Postqueue
|
2
|
-
MAX_ATTEMPTS = 5
|
3
|
-
|
4
|
-
class Base
|
5
|
-
# Processes many entries
|
6
|
-
#
|
7
|
-
# process batch_size: 100
|
8
|
-
def process(op: nil, batch_size: 100, &block)
|
9
|
-
status, result = item_class.transaction do
|
10
|
-
process_inside_transaction(op: op, batch_size: batch_size, &block)
|
11
|
-
end
|
12
|
-
|
13
|
-
raise result if status == :err
|
14
|
-
result
|
15
|
-
end
|
16
|
-
|
17
|
-
def process_one(op: nil, &block)
|
18
|
-
process(op: op, batch_size: 1, &block)
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
# The actual processing. Returns [ :ok, number-of-items ] or [ :err, exception ]
|
24
|
-
def process_inside_transaction(op:, batch_size:, &block)
|
25
|
-
batch = select_and_lock_batch(op: op, batch_size: batch_size)
|
26
|
-
|
27
|
-
match = batch.first
|
28
|
-
return [ :ok, nil ] unless match
|
29
|
-
|
30
|
-
entity_ids = batch.map(&:entity_id)
|
31
|
-
result, timing = run_callback(op: match.op, entity_ids: entity_ids, &block)
|
32
|
-
|
33
|
-
# Depending on the result either reprocess or delete all items
|
34
|
-
if result == false
|
35
|
-
postpone batch.map(&:id)
|
36
|
-
else
|
37
|
-
on_processing(match.op, entity_ids, timing)
|
38
|
-
item_class.where(id: batch.map(&:id)).delete_all
|
39
|
-
end
|
40
|
-
|
41
|
-
[ :ok, result ]
|
42
|
-
rescue => e
|
43
|
-
on_exception(e, match.op, entity_ids)
|
44
|
-
postpone batch.map(&:id)
|
45
|
-
[ :err, e ]
|
46
|
-
end
|
47
|
-
|
48
|
-
def postpone(ids)
|
49
|
-
item_class.connection.exec_query <<-SQL
|
50
|
-
UPDATE #{item_class.table_name}
|
51
|
-
SET failed_attempts = failed_attempts+1,
|
52
|
-
next_run_at = next_run_at + power(failed_attempts + 1, 1.5) * interval '10 second'
|
53
|
-
WHERE id IN (#{ids.join(',')})
|
54
|
-
SQL
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/lib/postqueue/base.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
module Postqueue
|
2
|
-
Timing = Struct.new(:avg_queue_time, :max_queue_time, :total_processing_time, :processing_time)
|
3
|
-
|
4
|
-
class Base
|
5
|
-
private
|
6
|
-
|
7
|
-
def batch_size(op:)
|
8
|
-
_ = op
|
9
|
-
1
|
10
|
-
end
|
11
|
-
|
12
|
-
def item_class
|
13
|
-
Postqueue::Item
|
14
|
-
end
|
15
|
-
|
16
|
-
def logger
|
17
|
-
Postqueue.logger
|
18
|
-
end
|
19
|
-
|
20
|
-
def on_processing(op, entity_ids, timing)
|
21
|
-
msg = "processing '#{op}' for id(s) #{entity_ids.join(',')}: "
|
22
|
-
msg += "processing #{entity_ids.length} items took #{'%.3f msecs' % timing.total_processing_time}"
|
23
|
-
|
24
|
-
msg += ", queue_time: avg: #{'%.3f msecs' % timing.avg_queue_time}/max: #{'%.3f msecs' % timing.max_queue_time}"
|
25
|
-
logger.info msg
|
26
|
-
end
|
27
|
-
|
28
|
-
def on_exception(exception, op, entity_ids)
|
29
|
-
logger.warn "processing '#{op}' for id(s) #{entity_ids.inspect}: caught #{exception}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.logger
|
34
|
-
Logger.new(STDERR)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
require "postqueue/base/enqueue"
|
39
|
-
require "postqueue/base/select_and_lock"
|
40
|
-
require "postqueue/base/processing"
|
41
|
-
require "postqueue/base/callback"
|