philotic 0.8.1 → 1.0.1
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 +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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2e126429cf9f92b56a49a1f1e609479736b965c1
|
4
|
+
data.tar.gz: 2b0f1b015e34e9e7d773973cee7b4d7657186229
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 18e0412f7f720e0a382e17f109d54472ec0d6328e5d739ed8eabdf45058e33f70eb322908335d28a8b3d1825f67d42f47a63f622b3bd0df19751b0648533c00a
|
7
|
+
data.tar.gz: 1f06ba6e3e167d1c4d79540c7555435754b8ebee2bc62a7e3787309ab4115ec815110f036d7a2c66819e68858f08eea4993447e396196f6fbb97086ccfa0f121
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -20,8 +20,8 @@ Philotic.config.message_return_handler = lambda do |basic_return, metadata, mess
|
|
20
20
|
Philotic.logger.warn { "Message returned. reply_text: #{basic_return.reply_text}" }
|
21
21
|
end
|
22
22
|
|
23
|
-
Philotic.subscribe(header_key: 'header_1') do |message
|
24
|
-
ap message
|
23
|
+
Philotic.subscribe(header_key: 'header_1') do |message|
|
24
|
+
ap message.attributes
|
25
25
|
end
|
26
26
|
|
27
27
|
# normally we'd do:
|
@@ -31,7 +31,7 @@ end
|
|
31
31
|
# to keep the parent thread alive while the subscribers do their thing
|
32
32
|
# but this infinite publish loop takes care of that
|
33
33
|
loop do
|
34
|
-
Philotic::
|
34
|
+
Philotic::Message.publish({header_key: "header_#{[1, 2].sample}"}, {payload_key: 'payload_value'})
|
35
35
|
# only send a message every two seconds so we can see whats going on
|
36
36
|
sleep 2
|
37
37
|
end
|
@@ -49,8 +49,8 @@ philotic.config.message_return_handler = lambda do |basic_return, metadata, mess
|
|
49
49
|
philotic.logger.warn { "Message returned. reply_text: #{basic_return.reply_text}" }
|
50
50
|
end
|
51
51
|
|
52
|
-
philotic.subscribe(header_key: 'header_1') do |message
|
53
|
-
ap message
|
52
|
+
philotic.subscribe(header_key: 'header_1') do |message|
|
53
|
+
ap message.attributes
|
54
54
|
end
|
55
55
|
|
56
56
|
# normally we'd do:
|
@@ -60,19 +60,16 @@ end
|
|
60
60
|
# to keep the parent thread alive while the subscribers do their thing
|
61
61
|
# but this infinite publish loop takes care of that
|
62
62
|
loop do
|
63
|
-
|
64
|
-
philotic.publish
|
63
|
+
message = Philotic::Message.new({header_key: "header_#{[1, 2].sample}"}, {payload_key: 'payload_value'})
|
64
|
+
philotic.publish message
|
65
65
|
# only send a message every two seconds so we can see whats going on
|
66
66
|
sleep 2
|
67
67
|
end
|
68
68
|
```
|
69
69
|
|
70
70
|
### Tested with the following Rubies
|
71
|
-
* 1.9.3
|
72
71
|
* 2.0.0
|
73
|
-
* 2.1.
|
74
|
-
*
|
75
|
-
* rbx-2
|
76
|
-
* jruby-19mode
|
72
|
+
* 2.1.x
|
73
|
+
* 2.2.x
|
74
|
+
* rbx-2
|
77
75
|
* ruby-head
|
78
|
-
* jruby-head
|
@@ -8,7 +8,7 @@ require 'philotic'
|
|
8
8
|
# Philotic.config.initialize_named_queues must be truthy to run Philotic.initialize_named_queue!
|
9
9
|
Philotic.config.initialize_named_queues = true
|
10
10
|
|
11
|
-
Philotic.initialize_named_queue!('
|
12
|
-
Philotic.initialize_named_queue!('
|
13
|
-
Philotic.initialize_named_queue!('test_queue', bindings: [{ :'x-match' => 'any',
|
14
|
-
Philotic.initialize_named_queue!('flaky_queue', bindings: [{ :'x-match' => 'any',
|
11
|
+
Philotic.initialize_named_queue!('mauve_queue', bindings: [{:'x-match' => 'all', hue: :M, available: true}])
|
12
|
+
Philotic.initialize_named_queue!('fuchsia_queue', bindings: [{:'x-match' => 'all', hue: :F, available: true}])
|
13
|
+
Philotic.initialize_named_queue!('test_queue', bindings: [{ :'x-match' => 'any', hue: :M, available: true }])
|
14
|
+
Philotic.initialize_named_queue!('flaky_queue', bindings: [{ :'x-match' => 'any', hue: :M, available: true }])
|
@@ -7,5 +7,8 @@ require 'rake'
|
|
7
7
|
|
8
8
|
require 'philotic/tasks'
|
9
9
|
# equivelant of:
|
10
|
-
# rake philotic:init_queues[examples/creating_named_queues/philotic_queues.yml]
|
10
|
+
# PHILOTIC_DELETE_EXISTING_QUEUES=true rake philotic:init_queues[examples/creating_named_queues/philotic_queues.yml]
|
11
|
+
|
12
|
+
# Philotic.config.self.config.delete_existing_queues must be truthy to redefine existing queues
|
13
|
+
ENV['PHILOTIC_DELETE_EXISTING_QUEUES'] = 'true'
|
11
14
|
Rake::Task['philotic:init_queues'].invoke(File.join(File.dirname(__FILE__), 'philotic_queues.yml'))
|
@@ -3,29 +3,29 @@ $:.unshift File.expand_path('../../../lib', __FILE__)
|
|
3
3
|
$stdout.sync = true
|
4
4
|
|
5
5
|
require 'philotic'
|
6
|
-
require 'philotic/
|
6
|
+
require 'philotic/dummy_message'
|
7
7
|
|
8
8
|
|
9
9
|
Philotic.logger.level = Logger::WARN
|
10
10
|
|
11
|
-
@
|
11
|
+
@message = Philotic::DummyMessage.new
|
12
12
|
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
13
|
+
@message.philotic_firehose = true
|
14
|
+
@message.philotic_product = 'rabbit'
|
15
|
+
@message.philotic_component = 'speed_test'
|
16
|
+
@message.philotic_message_type = 'ping'
|
17
17
|
|
18
|
-
@
|
19
|
-
@
|
18
|
+
@message.subject = 'Hey'
|
19
|
+
@message.available = true
|
20
20
|
|
21
|
-
@
|
22
|
-
@
|
21
|
+
@message.metadata = {mandatory: true}
|
22
|
+
@message.metadata = {app_id: 'PHX'}
|
23
23
|
|
24
24
|
def send_message number
|
25
|
-
@
|
26
|
-
@
|
25
|
+
@message.hue = [:F, :M].sample
|
26
|
+
@message.message = "Message #{number}: Hue - #{@message.hue == :M ? 'mauve' : 'fuchsia'}"
|
27
27
|
|
28
|
-
Philotic.publish @
|
28
|
+
Philotic.publish @message
|
29
29
|
|
30
30
|
end
|
31
31
|
|
@@ -35,5 +35,5 @@ loop do
|
|
35
35
|
send_message i
|
36
36
|
print "Message rate: #{(i/(Time.now - start)).round(2)}/sec \r"
|
37
37
|
i+= 1
|
38
|
-
sleep 0.
|
38
|
+
sleep 0.001
|
39
39
|
end
|
data/examples/simple_instance.rb
CHANGED
@@ -12,8 +12,8 @@ philotic.config.message_return_handler = lambda do |basic_return, metadata, mess
|
|
12
12
|
philotic.logger.warn { "Message returned. reply_text: #{basic_return.reply_text}" }
|
13
13
|
end
|
14
14
|
|
15
|
-
philotic.subscribe(header_key: 'header_1') do |message
|
16
|
-
ap message
|
15
|
+
philotic.subscribe(header_key: 'header_1') do |message|
|
16
|
+
ap message.attributes
|
17
17
|
end
|
18
18
|
|
19
19
|
# normally we'd do:
|
@@ -23,8 +23,8 @@ end
|
|
23
23
|
# to keep the parent thread alive while the subscribers do their thing
|
24
24
|
# but this infinite publish loop takes care of that
|
25
25
|
loop do
|
26
|
-
|
27
|
-
philotic.publish
|
26
|
+
message = Philotic::Message.new({header_key: "header_#{[1, 2].sample}"}, {payload_key: 'payload_value'})
|
27
|
+
philotic.publish message
|
28
28
|
# only send a message every two seconds so we can see whats going on
|
29
29
|
sleep 2
|
30
30
|
end
|
@@ -10,8 +10,8 @@ Philotic.config.message_return_handler = lambda do |basic_return, metadata, mess
|
|
10
10
|
Philotic.logger.warn { "Message returned. reply_text: #{basic_return.reply_text}" }
|
11
11
|
end
|
12
12
|
|
13
|
-
Philotic.subscribe(header_key: 'header_1') do |message
|
14
|
-
ap message
|
13
|
+
Philotic.subscribe(header_key: 'header_1') do |message|
|
14
|
+
ap header_key: message.header_key, payload_key: message.payload_key, methods: message.methods - Philotic::Message.new.methods
|
15
15
|
end
|
16
16
|
|
17
17
|
# normally we'd do:
|
@@ -21,7 +21,7 @@ end
|
|
21
21
|
# to keep the parent thread alive while the subscribers do their thing
|
22
22
|
# but this infinite publish loop takes care of that
|
23
23
|
loop do
|
24
|
-
Philotic::
|
24
|
+
Philotic::Message.publish({header_key: "header_#{[1, 2].sample}"}, {payload_key: 'payload_value'})
|
25
25
|
# only send a message every two seconds so we can see whats going on
|
26
26
|
sleep 2
|
27
27
|
end
|
@@ -6,20 +6,20 @@ require 'philotic'
|
|
6
6
|
require 'awesome_print'
|
7
7
|
|
8
8
|
# sometimes ack
|
9
|
-
Philotic.subscribe('flaky_queue', ack: true) do |message
|
10
|
-
ap message
|
9
|
+
Philotic.subscribe('flaky_queue', ack: true) do |message|
|
10
|
+
ap message.attributes
|
11
11
|
[true, false].sample ? acknowledge(message) : reject(message)
|
12
12
|
end
|
13
13
|
|
14
14
|
# always ack
|
15
|
-
Philotic.subscribe('flaky_queue', ack: true) do |message
|
16
|
-
ap message
|
15
|
+
Philotic.subscribe('flaky_queue', ack: true) do |message|
|
16
|
+
ap message.attributes
|
17
17
|
acknowledge(message, true)
|
18
18
|
end
|
19
19
|
|
20
20
|
# always reject
|
21
|
-
Philotic.subscribe('flaky_queue', ack: true) do |message
|
22
|
-
ap message
|
21
|
+
Philotic.subscribe('flaky_queue', ack: true) do |message|
|
22
|
+
ap message.attributes
|
23
23
|
reject message
|
24
24
|
end
|
25
25
|
Philotic.subscriber.endure
|
@@ -7,8 +7,8 @@ require 'awesome_print'
|
|
7
7
|
|
8
8
|
Philotic.config.load_file(File.join(File.dirname(__FILE__), '../../', 'Philotic.yml.example'))
|
9
9
|
|
10
|
-
Philotic.subscribe(philotic_firehose: true) do |message
|
11
|
-
ap message
|
10
|
+
Philotic.subscribe(philotic_firehose: true) do |message|
|
11
|
+
ap message.attributes
|
12
12
|
end
|
13
13
|
|
14
14
|
Philotic.subscriber.endure
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.unshift File.expand_path('../../../lib', __FILE__)
|
3
|
+
$stdout.sync = true
|
4
|
+
|
5
|
+
require 'philotic'
|
6
|
+
require 'awesome_print'
|
7
|
+
|
8
|
+
class NamedQueueConsumer < Philotic::Consumer
|
9
|
+
|
10
|
+
# subscribe to an existing named queue
|
11
|
+
subscribe_to :test_queue
|
12
|
+
|
13
|
+
#use acknowledgements
|
14
|
+
ack_messages
|
15
|
+
|
16
|
+
# REQUEUE the message with RabbitMQ if consume throws these errors. I.e., something went wrong with the consumer
|
17
|
+
# Only valid with ack_messages
|
18
|
+
requeueable_errors PossiblyTransientErrorOne, PossiblyTransientErrorTwo
|
19
|
+
|
20
|
+
# REJECT the message with RabbitMQ if consume throws these errors. I.e., The message is malformed/invalid
|
21
|
+
# Only valid with ack_messages
|
22
|
+
rejectable_errors BadMessageError
|
23
|
+
|
24
|
+
def consume(message)
|
25
|
+
ap named: message.attributes
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class AnonymousQueueConsumer < Philotic::Consumer
|
30
|
+
|
31
|
+
# subscribe anonymously to a set of headers:
|
32
|
+
# subscribe_to header_1: 'value_1',
|
33
|
+
# header_2: 'value_2',
|
34
|
+
# header_3: 'value_3'
|
35
|
+
subscribe_to philotic_firehose: true
|
36
|
+
|
37
|
+
def consume(message)
|
38
|
+
ap anon: message.attributes
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#run the consumers
|
43
|
+
AnonymousQueueConsumer.subscribe
|
44
|
+
NamedQueueConsumer.subscribe
|
45
|
+
|
46
|
+
# keep the parent thread alive
|
47
|
+
Philotic.endure
|
@@ -7,12 +7,12 @@ require 'awesome_print'
|
|
7
7
|
|
8
8
|
Philotic.config.load_file(File.join(File.dirname(__FILE__), '../../', 'Philotic.yml.example'))
|
9
9
|
|
10
|
-
Philotic.subscribe('
|
11
|
-
ap message
|
10
|
+
Philotic.subscribe('fuchsia_queue') do |message|
|
11
|
+
ap message.attributes
|
12
12
|
end
|
13
13
|
|
14
|
-
Philotic.subscribe('
|
15
|
-
ap message
|
14
|
+
Philotic.subscribe('mauve_queue') do |message|
|
15
|
+
ap message.attributes
|
16
16
|
end
|
17
17
|
|
18
18
|
Philotic.subscriber.endure
|
@@ -5,8 +5,8 @@ $stdout.sync = true
|
|
5
5
|
require 'philotic'
|
6
6
|
require 'awesome_print'
|
7
7
|
|
8
|
-
Philotic.subscribe('test_queue') do |message
|
9
|
-
ap message
|
8
|
+
Philotic.subscribe('test_queue') do |message|
|
9
|
+
ap message.attributes
|
10
10
|
end
|
11
11
|
|
12
|
-
Philotic.subscriber.endure
|
12
|
+
Philotic.subscriber.endure
|
data/lib/philotic.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'active_support/all'
|
2
1
|
require 'pathname'
|
3
2
|
|
4
3
|
module Philotic
|
@@ -16,8 +15,8 @@ require 'philotic/singleton'
|
|
16
15
|
require 'philotic/connection'
|
17
16
|
require 'philotic/version'
|
18
17
|
require 'philotic/config'
|
19
|
-
require 'philotic/
|
20
|
-
require 'philotic/event'
|
18
|
+
require 'philotic/message'
|
21
19
|
require 'philotic/publisher'
|
22
20
|
require 'philotic/subscriber'
|
21
|
+
require 'philotic/consumer'
|
23
22
|
require 'philotic/logging'
|
data/lib/philotic/config.rb
CHANGED
data/lib/philotic/connection.rb
CHANGED
data/lib/philotic/constants.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'philotic/singleton'
|
2
|
+
require 'philotic/subscriber'
|
3
|
+
|
4
|
+
module Philotic
|
5
|
+
class Consumer < Philotic::Subscriber
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def subscribe_to(subscription)
|
10
|
+
@subscription = subscription
|
11
|
+
end
|
12
|
+
|
13
|
+
def subscription
|
14
|
+
@subscription
|
15
|
+
end
|
16
|
+
|
17
|
+
def ack_messages
|
18
|
+
@ack_messages = true
|
19
|
+
end
|
20
|
+
|
21
|
+
def exclusive
|
22
|
+
@exclusive = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def ack_messages?
|
26
|
+
!!@ack_messages
|
27
|
+
end
|
28
|
+
|
29
|
+
def exclusive?
|
30
|
+
!!@exclusive
|
31
|
+
end
|
32
|
+
|
33
|
+
def requeueable_errors(*errors)
|
34
|
+
@requeueable_errors ||= Set.new
|
35
|
+
@requeueable_errors.merge errors
|
36
|
+
@requeueable_errors
|
37
|
+
end
|
38
|
+
|
39
|
+
def rejectable_errors(*errors)
|
40
|
+
@rejectable_errors ||= Set.new
|
41
|
+
@rejectable_errors.merge errors
|
42
|
+
@rejectable_errors
|
43
|
+
end
|
44
|
+
|
45
|
+
def subscribe
|
46
|
+
new(Philotic.connection).tap do |instance|
|
47
|
+
instance.subscribe
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def subscription_options
|
52
|
+
{
|
53
|
+
manual_ack: ack_messages?,
|
54
|
+
exclusive: exclusive?,
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def subscribe
|
60
|
+
super(self.class.subscription, self.class.subscription_options) do |message|
|
61
|
+
_consume(message)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def consume(message)
|
66
|
+
raise NotImplementedError
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def _consume(message)
|
72
|
+
if self.class.ack_messages?
|
73
|
+
begin
|
74
|
+
consume(message)
|
75
|
+
rescue => e
|
76
|
+
|
77
|
+
if self.class.requeueable_errors.include? e.class
|
78
|
+
reject(message, true)
|
79
|
+
return
|
80
|
+
elsif self.class.rejectable_errors.include? e.class
|
81
|
+
reject(message, false)
|
82
|
+
return
|
83
|
+
else
|
84
|
+
raise e
|
85
|
+
end
|
86
|
+
end
|
87
|
+
acknowledge(message)
|
88
|
+
else
|
89
|
+
consume(message)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|