philotic 0.8.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/.travis.yml +5 -6
- data/README.md +10 -13
- data/examples/creating_named_queues/manually.rb +4 -4
- data/examples/creating_named_queues/with_rake.rb +4 -1
- data/examples/publishing/publish.rb +14 -14
- data/examples/simple_instance.rb +4 -4
- data/examples/simple_singleton.rb +3 -3
- data/examples/subscribing/acks.rb +6 -6
- data/examples/subscribing/anonymous_queue.rb +2 -2
- data/examples/subscribing/consumer.rb +47 -0
- data/examples/subscribing/multiple_named_queues.rb +4 -4
- data/examples/subscribing/named_queue.rb +3 -3
- data/lib/philotic.rb +2 -3
- data/lib/philotic/config.rb +1 -1
- data/lib/philotic/connection.rb +1 -0
- data/lib/philotic/constants.rb +1 -1
- data/lib/philotic/consumer.rb +93 -0
- data/lib/philotic/{dummy_event.rb → dummy_message.rb} +3 -3
- data/lib/philotic/logging.rb +1 -1
- data/lib/philotic/logging/logger.rb +6 -6
- data/lib/philotic/logging/{event.rb → message.rb} +2 -2
- data/lib/philotic/message.rb +146 -0
- data/lib/philotic/publisher.rb +24 -24
- data/lib/philotic/subscriber.rb +9 -12
- data/lib/philotic/version.rb +1 -1
- data/philotic.gemspec +8 -11
- data/philotic_queues.yml.example +8 -8
- data/spec/philotic/connection_spec.rb +2 -0
- data/spec/philotic/consumer_spec.rb +186 -0
- data/spec/philotic/logging/logger_spec.rb +15 -15
- data/spec/philotic/message_spec.rb +147 -0
- data/spec/philotic/publisher_spec.rb +39 -38
- data/spec/philotic/subscriber_spec.rb +6 -3
- metadata +173 -144
- data/lib/philotic/event.rb +0 -100
- data/lib/philotic/routable.rb +0 -98
- data/spec/philotic/event_spec.rb +0 -109
- data/spec/philotic/routable_spec.rb +0 -54
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'philotic/
|
1
|
+
require 'philotic/message'
|
2
2
|
|
3
3
|
module Philotic
|
4
|
-
class
|
4
|
+
class DummyMessage < Philotic::Message
|
5
5
|
attr_payload :subject
|
6
6
|
attr_payload :message
|
7
|
-
attr_routable :
|
7
|
+
attr_routable :hue
|
8
8
|
attr_routable :available
|
9
9
|
end
|
10
10
|
end
|
data/lib/philotic/logging.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
require 'logger'
|
2
|
-
require 'philotic/logging/
|
2
|
+
require 'philotic/logging/message'
|
3
3
|
|
4
4
|
module Philotic
|
5
5
|
module Logging
|
6
6
|
class Logger < ::Logger
|
7
7
|
|
8
|
-
attr_writer :
|
8
|
+
attr_writer :message_class
|
9
9
|
attr_accessor :connection
|
10
10
|
|
11
|
-
def
|
12
|
-
@
|
11
|
+
def message_class
|
12
|
+
@message_class ||= Philotic::Logging::Message
|
13
13
|
end
|
14
14
|
|
15
15
|
def add(severity, message = nil, progname = nil)
|
@@ -28,8 +28,8 @@ module Philotic
|
|
28
28
|
end
|
29
29
|
@logdev.write(format_message(format_severity(severity), Time.now, progname, message))
|
30
30
|
begin
|
31
|
-
|
32
|
-
connection.publish
|
31
|
+
message = message_class.new(severity, message, progname)
|
32
|
+
connection.publish message if connection
|
33
33
|
rescue => e
|
34
34
|
@logdev.write(format_message(format_severity(Logger::ERROR), Time.now, progname, e.message))
|
35
35
|
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'philotic/constants'
|
2
|
+
require 'philotic/singleton'
|
3
|
+
|
4
|
+
module Philotic
|
5
|
+
class Message
|
6
|
+
|
7
|
+
attr_accessor :connection, :publish_error, :delivery_info
|
8
|
+
attr_writer :published
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def attr_routable_accessors
|
12
|
+
@attr_routable_accessors ||= Set.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def attr_payload_accessors
|
16
|
+
@attr_payload_accessors ||= Set.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def attr_routable(*names)
|
20
|
+
attr_routable_accessors.merge(names)
|
21
|
+
attr_accessor(*names)
|
22
|
+
end
|
23
|
+
|
24
|
+
def attr_payload(*names)
|
25
|
+
attr_payload_accessors.merge(names)
|
26
|
+
attr_accessor(*names)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(routables={}, payloads={}, connection=nil)
|
31
|
+
self.timestamp = Time.now.to_i
|
32
|
+
self.philotic_firehose = true
|
33
|
+
self.connection = connection
|
34
|
+
|
35
|
+
# dynamically insert any passed in routables into both attr_routable
|
36
|
+
# and attr_payload
|
37
|
+
# result: ability to arbitrarily send a easily routable hash
|
38
|
+
# over into the bus
|
39
|
+
_set_routables_or_payloads(:routable, routables)
|
40
|
+
_set_routables_or_payloads(:payload, payloads)
|
41
|
+
|
42
|
+
@published = false
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.inherited(sub_class)
|
46
|
+
sub_class.attr_routable(*Philotic::PHILOTIC_HEADERS)
|
47
|
+
sub_class.attr_routable(*self.attr_routable_accessors.dup)
|
48
|
+
sub_class.attr_payload(*self.attr_payload_accessors.dup)
|
49
|
+
end
|
50
|
+
|
51
|
+
self.inherited(self)
|
52
|
+
|
53
|
+
Philotic::MESSAGE_OPTIONS.each do |message_option|
|
54
|
+
attr_reader message_option
|
55
|
+
define_method :"#{message_option}=" do |val|
|
56
|
+
instance_variable_set(:"@#{message_option}", val)
|
57
|
+
self.metadata[message_option] = val
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def connection
|
62
|
+
@connection ||= Philotic.connection
|
63
|
+
end
|
64
|
+
|
65
|
+
def published?
|
66
|
+
!!@published
|
67
|
+
end
|
68
|
+
|
69
|
+
def publish
|
70
|
+
connection.publish self
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.publish(*args)
|
74
|
+
self.new(*args).publish
|
75
|
+
end
|
76
|
+
|
77
|
+
def delivery_tag
|
78
|
+
delivery_info.try(:delivery_tag)
|
79
|
+
end
|
80
|
+
|
81
|
+
def payload
|
82
|
+
_payload_or_headers(:payload)
|
83
|
+
end
|
84
|
+
|
85
|
+
def headers
|
86
|
+
_payload_or_headers(:routable)
|
87
|
+
end
|
88
|
+
|
89
|
+
def attributes
|
90
|
+
payload.merge headers
|
91
|
+
end
|
92
|
+
|
93
|
+
def metadata
|
94
|
+
@metadata ||= {}
|
95
|
+
end
|
96
|
+
|
97
|
+
def metadata=(options)
|
98
|
+
@metadata ||= {}
|
99
|
+
@metadata.merge! options
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def _payload_or_headers(payload_or_headers)
|
105
|
+
attribute_hash = {}
|
106
|
+
self.class.send("attr_#{payload_or_headers}_accessors").each do |attr|
|
107
|
+
attr = attr.to_sym
|
108
|
+
attribute_hash[attr] = send(attr)
|
109
|
+
end
|
110
|
+
attribute_hash
|
111
|
+
end
|
112
|
+
|
113
|
+
def _set_routables_or_payloads(type, attrs)
|
114
|
+
attrs.each do |key, value|
|
115
|
+
if self.respond_to?(:"#{key}=")
|
116
|
+
send(:"#{key}=", value)
|
117
|
+
elsif self.class == Philotic::Message
|
118
|
+
_set_message_attribute(type, key, value)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def _set_message_attribute(type, key, value)
|
124
|
+
self.class.send("attr_#{type}_accessors").merge([key])
|
125
|
+
_set_message_attribute_accessor(key, value)
|
126
|
+
end
|
127
|
+
|
128
|
+
def _set_message_attribute_accessor(attr, value)
|
129
|
+
_set_message_attribute_getter(attr)
|
130
|
+
_set_message_attribute_setter(attr)
|
131
|
+
self.send(:"#{attr}=", value)
|
132
|
+
end
|
133
|
+
|
134
|
+
def _set_message_attribute_getter(attr)
|
135
|
+
self.define_singleton_method :"#{attr}" do
|
136
|
+
instance_variable_get(:"@#{attr}")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def _set_message_attribute_setter(attr)
|
141
|
+
self.define_singleton_method :"#{attr}=" do |v|
|
142
|
+
instance_variable_set(:"@#{attr}", v)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
data/lib/philotic/publisher.rb
CHANGED
@@ -4,7 +4,7 @@ module Philotic
|
|
4
4
|
class Publisher
|
5
5
|
|
6
6
|
attr_accessor :connection
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :log_message_handler
|
8
8
|
|
9
9
|
def initialize(connection)
|
10
10
|
@connection = connection
|
@@ -18,16 +18,16 @@ module Philotic
|
|
18
18
|
connection.config
|
19
19
|
end
|
20
20
|
|
21
|
-
def publish(
|
22
|
-
|
23
|
-
|
21
|
+
def publish(message)
|
22
|
+
metadata = {headers: message.headers}
|
23
|
+
metadata.merge!(message.metadata) if message.metadata
|
24
24
|
begin
|
25
|
-
|
25
|
+
message.published = _publish(message.payload, metadata)
|
26
26
|
rescue => e
|
27
|
-
|
27
|
+
message.publish_error = e
|
28
28
|
logger.error e.message
|
29
29
|
end
|
30
|
-
|
30
|
+
message
|
31
31
|
end
|
32
32
|
|
33
33
|
def normalize_payload_times(payload)
|
@@ -41,45 +41,45 @@ module Philotic
|
|
41
41
|
end
|
42
42
|
|
43
43
|
private
|
44
|
-
def _publish(payload,
|
44
|
+
def _publish(payload, metadata = {})
|
45
45
|
if config.disable_publish
|
46
|
-
|
46
|
+
log_message_published(:warn, metadata, payload, 'attempted to publish a message when publishing is disabled.')
|
47
47
|
return false
|
48
48
|
end
|
49
49
|
connection.connect!
|
50
50
|
unless connection.connected?
|
51
|
-
|
51
|
+
log_message_published(:error, metadata, payload, 'unable to publish message, not connected to RabbitMQ')
|
52
52
|
return false
|
53
53
|
end
|
54
|
-
|
54
|
+
metadata = merge_metadata(metadata)
|
55
55
|
|
56
56
|
payload = normalize_payload_times(payload)
|
57
57
|
|
58
|
-
connection.exchange.publish(payload.to_json,
|
59
|
-
|
58
|
+
connection.exchange.publish(payload.to_json, metadata)
|
59
|
+
log_message_published(:debug, metadata, payload, 'published message')
|
60
60
|
true
|
61
61
|
end
|
62
62
|
|
63
|
-
def merge_metadata(
|
63
|
+
def merge_metadata(metadata)
|
64
64
|
publish_defaults = {}
|
65
65
|
Philotic::MESSAGE_OPTIONS.each do |key|
|
66
66
|
publish_defaults[key] = config.send(key.to_s)
|
67
67
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
metadata = publish_defaults.merge metadata
|
69
|
+
metadata[:headers] ||= {}
|
70
|
+
metadata[:headers] = {philotic_firehose: true}.merge(metadata[:headers])
|
71
|
+
metadata
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
75
|
-
@
|
74
|
+
def on_publish_message(&block)
|
75
|
+
@log_message_handler = block
|
76
76
|
end
|
77
77
|
|
78
|
-
def
|
79
|
-
if @
|
80
|
-
@
|
78
|
+
def log_message_published(severity, metadata, payload, message)
|
79
|
+
if @log_message_handler
|
80
|
+
@log_message_handler.call(severity, metadata, payload, message)
|
81
81
|
else
|
82
|
-
logger.send(severity, "#{message};
|
82
|
+
logger.send(severity, "#{message}; metadata:#{metadata}, payload:#{payload.to_json}")
|
83
83
|
end
|
84
84
|
end
|
85
85
|
end
|
data/lib/philotic/subscriber.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'philotic/constants'
|
2
|
+
require 'philotic/message'
|
2
3
|
|
3
4
|
module Philotic
|
4
5
|
class Subscriber
|
@@ -17,18 +18,14 @@ module Philotic
|
|
17
18
|
connection.config
|
18
19
|
end
|
19
20
|
|
20
|
-
def subscription_callback(
|
21
|
+
def subscription_callback(&block)
|
21
22
|
lambda do |delivery_info, metadata, payload|
|
22
23
|
hash_payload = JSON.parse payload
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
headers: metadata[:headers],
|
27
|
-
delivery_info: delivery_info,
|
28
|
-
attributes: metadata[:headers] ? hash_payload.merge(metadata[:headers]) : hash_payload
|
29
|
-
}
|
25
|
+
message = Philotic::Message.new(metadata[:headers], hash_payload)
|
26
|
+
message.delivery_info = delivery_info
|
30
27
|
|
31
|
-
instance_exec(
|
28
|
+
instance_exec(message, &block)
|
32
29
|
end
|
33
30
|
end
|
34
31
|
|
@@ -40,7 +37,7 @@ module Philotic
|
|
40
37
|
|
41
38
|
queue = initialize_queue(subscription_settings)
|
42
39
|
|
43
|
-
queue.subscribe(subscription_settings[:subscribe_options], &subscription_callback(
|
40
|
+
queue.subscribe(subscription_settings[:subscribe_options], &subscription_callback(&block))
|
44
41
|
|
45
42
|
end
|
46
43
|
|
@@ -53,7 +50,7 @@ module Philotic
|
|
53
50
|
|
54
51
|
def get_subscription_settings(subscription, subscribe_options)
|
55
52
|
|
56
|
-
if
|
53
|
+
if [Symbol, String].include? subscription.class
|
57
54
|
queue_name = subscription
|
58
55
|
subscription = subscribe_options
|
59
56
|
queue_options = Philotic::DEFAULT_NAMED_QUEUE_OPTIONS
|
@@ -79,11 +76,11 @@ module Philotic
|
|
79
76
|
end
|
80
77
|
|
81
78
|
def acknowledge(message, up_to_and_including=false)
|
82
|
-
connection.channel.acknowledge(message
|
79
|
+
connection.channel.acknowledge(message.delivery_tag, up_to_and_including)
|
83
80
|
end
|
84
81
|
|
85
82
|
def reject(message, requeue=true)
|
86
|
-
connection.channel.reject(message
|
83
|
+
connection.channel.reject(message.delivery_tag, requeue)
|
87
84
|
end
|
88
85
|
|
89
86
|
def subscribe_to_any(options = {})
|
data/lib/philotic/version.rb
CHANGED
data/philotic.gemspec
CHANGED
@@ -16,20 +16,17 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = Philotic::VERSION
|
17
17
|
gem.licenses = ['MIT']
|
18
18
|
|
19
|
-
|
20
19
|
gem.add_development_dependency 'codeclimate-test-reporter'
|
21
|
-
gem.add_development_dependency 'bundler', '
|
22
|
-
gem.add_development_dependency '
|
23
|
-
gem.add_development_dependency '
|
24
|
-
gem.add_development_dependency '
|
25
|
-
gem.add_development_dependency 'rspec', '
|
26
|
-
gem.add_development_dependency '
|
27
|
-
gem.add_development_dependency 'timecop', '~> 0.7'
|
20
|
+
gem.add_development_dependency 'bundler', '>= 1.6'
|
21
|
+
gem.add_development_dependency 'pry', '>= 0.10'
|
22
|
+
gem.add_development_dependency 'rake', '>= 10.3'
|
23
|
+
gem.add_development_dependency 'rspec', '>= 3.1'
|
24
|
+
gem.add_development_dependency 'rspec-its', '>= 1.1'
|
25
|
+
gem.add_development_dependency 'timecop', '>= 0.7'
|
28
26
|
gem.add_development_dependency 'simplecov'
|
29
27
|
|
30
28
|
gem.add_dependency 'activesupport', '>= 3.2'
|
31
|
-
gem.add_dependency '
|
32
|
-
gem.add_dependency 'awesome_print', '~> 1.2'
|
29
|
+
gem.add_dependency 'awesome_print', '>= 1.2'
|
33
30
|
gem.add_dependency 'bunny', '>= 1.6'
|
34
|
-
gem.add_dependency 'json', '
|
31
|
+
gem.add_dependency 'json', '>= 1.8'
|
35
32
|
end
|
data/philotic_queues.yml.example
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
available_or_mauve:
|
2
|
+
hue: Mauve
|
3
3
|
available: true
|
4
4
|
x-match: any
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
available_mauve:
|
7
|
+
hue: Mauve
|
8
8
|
available: true
|
9
9
|
x-match: all
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
available_or_fuchsia:
|
12
|
+
hue: Fuchsia
|
13
13
|
available: true
|
14
14
|
x-match: any
|
15
15
|
|
16
|
-
|
17
|
-
|
16
|
+
available_fuchsia:
|
17
|
+
hue: Fuchsia
|
18
18
|
available: true
|
19
19
|
x-match: all
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'philotic/consumer'
|
4
|
+
require 'philotic/connection'
|
5
|
+
require 'philotic/subscriber'
|
6
|
+
|
7
|
+
|
8
|
+
describe Philotic::Consumer do
|
9
|
+
let(:named_queue) { :named_queue }
|
10
|
+
let(:anonymous_subscription) { {
|
11
|
+
header_1: :value_1,
|
12
|
+
header_2: :value_2,
|
13
|
+
header_3: :value_3,
|
14
|
+
} }
|
15
|
+
subject { Class.new Philotic::Consumer }
|
16
|
+
|
17
|
+
describe '.subscribe_to' do
|
18
|
+
it 'sets the class variable @subscription' do
|
19
|
+
|
20
|
+
expect(subject.subscription).not_to be
|
21
|
+
|
22
|
+
subject.subscribe_to named_queue
|
23
|
+
expect(subject.subscription).to eq named_queue
|
24
|
+
|
25
|
+
subject.subscribe_to anonymous_subscription
|
26
|
+
expect(subject.subscription).to eq anonymous_subscription
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '.ack_messages' do
|
31
|
+
it 'sets the class variable @ack_messages' do
|
32
|
+
expect(subject.ack_messages?).not_to be true
|
33
|
+
subject.ack_messages
|
34
|
+
expect(subject.ack_messages?).to be true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '.exclusive' do
|
39
|
+
it 'sets the class variable @exclusive' do
|
40
|
+
expect(subject).not_to be_exclusive
|
41
|
+
subject.exclusive
|
42
|
+
expect(subject).to be_exclusive
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '.requeueable_errors' do
|
47
|
+
it 'maintains a set of requeueable errors' do
|
48
|
+
expect(subject.requeueable_errors).to be_empty
|
49
|
+
expect(subject.requeueable_errors(RuntimeError).size).to be 1
|
50
|
+
expect(subject.requeueable_errors).to include(RuntimeError)
|
51
|
+
|
52
|
+
expect(subject.requeueable_errors(RuntimeError, NotImplementedError).size).to be 2
|
53
|
+
expect(subject.requeueable_errors).to include(NotImplementedError)
|
54
|
+
|
55
|
+
|
56
|
+
# don't allow dupes
|
57
|
+
expect(subject.requeueable_errors(RuntimeError, NotImplementedError).size).to be 2
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '.rejectable_errors' do
|
63
|
+
it 'maintains a set of rejectable errors' do
|
64
|
+
expect(subject.rejectable_errors).to be_empty
|
65
|
+
expect(subject.rejectable_errors(RuntimeError).size).to be 1
|
66
|
+
expect(subject.rejectable_errors).to include(RuntimeError)
|
67
|
+
|
68
|
+
expect(subject.rejectable_errors(RuntimeError, NotImplementedError).size).to be 2
|
69
|
+
expect(subject.rejectable_errors).to include(NotImplementedError)
|
70
|
+
|
71
|
+
|
72
|
+
# don't allow dupes
|
73
|
+
expect(subject.rejectable_errors(RuntimeError, NotImplementedError).size).to be 2
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '.subscribe' do
|
79
|
+
let (:connection) { instance_double Philotic::Connection }
|
80
|
+
let (:consumer_instance) { instance_double subject }
|
81
|
+
it 'proxies to, and returns, a new instance' do
|
82
|
+
expect(Philotic).to receive(:connection).and_return(connection)
|
83
|
+
expect(subject).to receive(:new).and_return(consumer_instance)
|
84
|
+
expect(consumer_instance).to receive(:subscribe)
|
85
|
+
|
86
|
+
expect(subject.subscribe).to be consumer_instance
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#subscription_options' do
|
91
|
+
it 'returns a hash with the exclusive and manual_ack options' do
|
92
|
+
expect(subject.subscription_options).to match({manual_ack: false, exclusive: false})
|
93
|
+
|
94
|
+
subject.ack_messages
|
95
|
+
expect(subject.subscription_options).to match({manual_ack: true, exclusive: false})
|
96
|
+
|
97
|
+
subject.exclusive
|
98
|
+
expect(subject.subscription_options).to match({manual_ack: true, exclusive: true})
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#subscribe' do
|
103
|
+
it 'proxies to Philotic::Subscriber#subscribe' do
|
104
|
+
subject.subscribe_to named_queue
|
105
|
+
subject.ack_messages
|
106
|
+
subject.exclusive
|
107
|
+
|
108
|
+
expect_any_instance_of(Philotic::Subscriber).to receive(:subscribe).with(named_queue, manual_ack: true, exclusive: true)
|
109
|
+
|
110
|
+
subject.subscribe
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#consume' do
|
115
|
+
subject { (Class.new(Philotic::Consumer)).new(nil) }
|
116
|
+
|
117
|
+
it 'raises an error unless the inheriting class redefines it' do
|
118
|
+
expect { subject.consume(nil) }.to raise_error(NotImplementedError)
|
119
|
+
|
120
|
+
subject.define_singleton_method :consume do |message|
|
121
|
+
# no op
|
122
|
+
end
|
123
|
+
|
124
|
+
expect { subject.consume(nil) }.to_not raise_error
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe '#_consume' do
|
129
|
+
subject { (Class.new(Philotic::Consumer)).new(nil) }
|
130
|
+
let(:message) { instance_double Philotic::Message }
|
131
|
+
|
132
|
+
it 'proxies to #consume' do
|
133
|
+
expect(subject).to receive(:consume).with(message)
|
134
|
+
|
135
|
+
subject.send(:_consume, message)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'acknowledges messages when @ack_messages is set' do
|
139
|
+
subject.class.ack_messages
|
140
|
+
|
141
|
+
subject.define_singleton_method :consume do |message|
|
142
|
+
# no op
|
143
|
+
end
|
144
|
+
|
145
|
+
expect(subject).to receive(:acknowledge).with(message)
|
146
|
+
|
147
|
+
subject.send(:_consume, message)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'requeues messages when @ack_messages is set and a requeueable error is thrown' do
|
151
|
+
subject.class.ack_messages
|
152
|
+
subject.class.requeueable_errors(RuntimeError)
|
153
|
+
|
154
|
+
subject.define_singleton_method :consume do |message|
|
155
|
+
raise RuntimeError.new 'oops'
|
156
|
+
end
|
157
|
+
|
158
|
+
expect(subject).to receive(:reject).with(message, true)
|
159
|
+
|
160
|
+
subject.send(:_consume, message)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'rejects messages when @ack_messages is set and a rejectable error is thrown' do
|
164
|
+
subject.class.ack_messages
|
165
|
+
subject.class.rejectable_errors(RuntimeError)
|
166
|
+
|
167
|
+
subject.define_singleton_method :consume do |message|
|
168
|
+
raise RuntimeError.new 'oops'
|
169
|
+
end
|
170
|
+
|
171
|
+
expect(subject).to receive(:reject).with(message, false)
|
172
|
+
|
173
|
+
subject.send(:_consume, message)
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'raises all non-requeueable and non-rejectable errors' do
|
177
|
+
subject.class.ack_messages
|
178
|
+
|
179
|
+
subject.define_singleton_method :consume do |message|
|
180
|
+
raise RuntimeError.new 'oops'
|
181
|
+
end
|
182
|
+
|
183
|
+
expect {subject.send(:_consume, message)}.to raise_error RuntimeError
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|