postqueue 0.2.1 → 0.4.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.
- 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"
|