euston-rabbitmq 1.0.0 → 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.
- data/euston-rabbitmq.gemspec +10 -8
- data/lib/euston-rabbitmq/bindings/command_handler_binder.rb +24 -0
- data/lib/euston-rabbitmq/bindings/event_handler_binder.rb +32 -0
- data/lib/euston-rabbitmq/bindings/handler_binder.rb +25 -0
- data/lib/euston-rabbitmq/constant_loader.rb +26 -0
- data/lib/euston-rabbitmq/handler_finder.rb +57 -0
- data/lib/euston-rabbitmq/handler_reference.rb +11 -0
- data/lib/euston-rabbitmq/message_buffer.rb +1 -2
- data/lib/euston-rabbitmq/read_model/message_buffer.rb +7 -2
- data/lib/euston-rabbitmq/{handler_bindings.rb → subscriptions/retriable_subscription.rb} +22 -41
- data/lib/euston-rabbitmq/version.rb +1 -1
- data/lib/euston-rabbitmq.rb +3 -1
- data/spec/constant_loader_spec.rb +38 -0
- data/spec/handler_finder_spec.rb +48 -0
- metadata +45 -43
- data/Gemfile.lock +0 -103
- data/lib/euston-rabbitmq/buffered_message_dispatcher.rb +0 -48
- data/lib/euston-rabbitmq/command_handler_bindings.rb +0 -30
- data/lib/euston-rabbitmq/event_handler_binding.rb +0 -114
- data/lib/euston-rabbitmq/event_handler_bindings.rb +0 -30
- data/lib/euston-rabbitmq/event_store_dispatcher.rb +0 -45
data/euston-rabbitmq.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'euston-rabbitmq'
|
3
|
-
s.version = '1.0.
|
3
|
+
s.version = '1.0.1'
|
4
4
|
s.platform = RUBY_PLATFORM.to_s == 'java' ? 'java' : Gem::Platform::RUBY
|
5
5
|
s.authors = ['Lee Henson', 'Guy Boertje']
|
6
6
|
s.email = ['lee.m.henson@gmail.com', 'guyboertje@gmail.com']
|
@@ -11,20 +11,19 @@ Gem::Specification.new do |s|
|
|
11
11
|
# = MANIFEST =
|
12
12
|
s.files = %w[
|
13
13
|
Gemfile
|
14
|
-
Gemfile.lock
|
15
14
|
Rakefile
|
16
15
|
euston-rabbitmq.gemspec
|
17
16
|
lib/euston-rabbitmq.rb
|
18
|
-
lib/euston-rabbitmq/
|
19
|
-
lib/euston-rabbitmq/
|
17
|
+
lib/euston-rabbitmq/bindings/command_handler_binder.rb
|
18
|
+
lib/euston-rabbitmq/bindings/event_handler_binder.rb
|
19
|
+
lib/euston-rabbitmq/bindings/handler_binder.rb
|
20
20
|
lib/euston-rabbitmq/command_handlers/retry_failed_message.rb
|
21
|
+
lib/euston-rabbitmq/constant_loader.rb
|
21
22
|
lib/euston-rabbitmq/errors.rb
|
22
|
-
lib/euston-rabbitmq/event_handler_binding.rb
|
23
|
-
lib/euston-rabbitmq/event_handler_bindings.rb
|
24
23
|
lib/euston-rabbitmq/event_handlers/message_failure.rb
|
25
|
-
lib/euston-rabbitmq/event_store_dispatcher.rb
|
26
24
|
lib/euston-rabbitmq/exchanges.rb
|
27
|
-
lib/euston-rabbitmq/
|
25
|
+
lib/euston-rabbitmq/handler_finder.rb
|
26
|
+
lib/euston-rabbitmq/handler_reference.rb
|
28
27
|
lib/euston-rabbitmq/message_buffer.rb
|
29
28
|
lib/euston-rabbitmq/message_logger.rb
|
30
29
|
lib/euston-rabbitmq/queue.rb
|
@@ -32,10 +31,13 @@ Gem::Specification.new do |s|
|
|
32
31
|
lib/euston-rabbitmq/read_model/failed_message.rb
|
33
32
|
lib/euston-rabbitmq/read_model/message_buffer.rb
|
34
33
|
lib/euston-rabbitmq/read_model/message_log.rb
|
34
|
+
lib/euston-rabbitmq/subscriptions/retriable_subscription.rb
|
35
35
|
lib/euston-rabbitmq/version.rb
|
36
36
|
spec/command_buffer_spec.rb
|
37
|
+
spec/constant_loader_spec.rb
|
37
38
|
spec/event_buffer_spec.rb
|
38
39
|
spec/exchange_declaration_spec.rb
|
40
|
+
spec/handler_finder_spec.rb
|
39
41
|
spec/message_failure_spec.rb
|
40
42
|
spec/mt_safe_queue_subscription_spec.rb
|
41
43
|
spec/safe_queue_subscription_spec.rb
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Euston
|
2
|
+
module RabbitMq
|
3
|
+
class CommandHandlerBinder < HandlerBinder
|
4
|
+
private
|
5
|
+
|
6
|
+
def ensure_bindings_exist_for_reference channel, reference
|
7
|
+
queue_name = :command_handlers
|
8
|
+
queue = get_command_handler_queue channel, queue_name
|
9
|
+
|
10
|
+
routing_key = "commands.#{reference.name.to_s.underscore}"
|
11
|
+
|
12
|
+
EUSTON_LOG.debug "Ensuring routing key exists for queue #{queue_name}: #{routing_key}"
|
13
|
+
|
14
|
+
exchange = get_exchange channel, :commands
|
15
|
+
queue.bind exchange, :routing_key => routing_key
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_command_handler_queue channel, queue_name
|
19
|
+
EUSTON_LOG.debug "Ensuring command handler queue exists: #{queue_name}" if @command_handler_queue.nil?
|
20
|
+
@command_handler_queue ||= get_queue channel, queue_name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Euston
|
2
|
+
module RabbitMq
|
3
|
+
class EventHandlerBinder < HandlerBinder
|
4
|
+
private
|
5
|
+
|
6
|
+
def ensure_bindings_exist_for_reference channel, reference
|
7
|
+
queue_name = reference.name.to_s.underscore
|
8
|
+
|
9
|
+
EUSTON_LOG.debug "Ensuring event handler queue exists: #{queue_name}"
|
10
|
+
|
11
|
+
queue = get_queue channel, queue_name
|
12
|
+
|
13
|
+
prefix = '__event_handler__'
|
14
|
+
|
15
|
+
methods = reference.handler.public_instance_methods(false)
|
16
|
+
methods = methods.select { |method| method.to_s.start_with? prefix }
|
17
|
+
methods = methods.map { |method| method.to_s[prefix.length, method.to_s.length - prefix.length] }
|
18
|
+
methods = methods.map { |method| method.split('__').first }
|
19
|
+
|
20
|
+
exchange = get_exchange channel, :events
|
21
|
+
|
22
|
+
methods.uniq.each do |method|
|
23
|
+
routing_key = "events.#{method}"
|
24
|
+
|
25
|
+
EUSTON_LOG.debug "Ensuring routing key exists for queue #{queue_name}: #{routing_key}"
|
26
|
+
|
27
|
+
queue.bind exchange, :routing_key => routing_key
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Euston
|
2
|
+
module RabbitMq
|
3
|
+
class HandlerBinder
|
4
|
+
include Euston::RabbitMq::Queues
|
5
|
+
include Euston::RabbitMq::Exchanges
|
6
|
+
|
7
|
+
def initialize references
|
8
|
+
@references = references
|
9
|
+
end
|
10
|
+
|
11
|
+
def ensure_bindings_exist
|
12
|
+
begin
|
13
|
+
channel = AMQP::Channel.new
|
14
|
+
channel.prefetch 1
|
15
|
+
|
16
|
+
@references.each do |reference|
|
17
|
+
ensure_bindings_exist_for_reference channel, reference
|
18
|
+
end
|
19
|
+
ensure
|
20
|
+
channel.disconnect unless channel.nil?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Euston
|
2
|
+
module RabbitMq
|
3
|
+
class ConstantLoader
|
4
|
+
include Hollywood
|
5
|
+
|
6
|
+
def load string
|
7
|
+
namespace = Object
|
8
|
+
found = true
|
9
|
+
|
10
|
+
string.split('::').each do |segment|
|
11
|
+
if found && namespace.const_defined?(segment)
|
12
|
+
namespace = namespace.const_get segment.to_sym
|
13
|
+
else
|
14
|
+
found = false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
if found
|
19
|
+
callback :hit, namespace
|
20
|
+
else
|
21
|
+
callback :miss, string
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Euston
|
2
|
+
module RabbitMq
|
3
|
+
class HandlerFinder
|
4
|
+
def initialize required_mixins = []
|
5
|
+
@namespaces = []
|
6
|
+
@constant_loader = ConstantLoader.new.when(:hit => method(:store_found_constant), :miss => method(:log_failed_lookup))
|
7
|
+
@required_mixins = required_mixins
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :namespaces
|
11
|
+
|
12
|
+
def find
|
13
|
+
filter_namespaces_list
|
14
|
+
map_namespaces_to_references
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def filter_namespaces_list
|
20
|
+
@namespaces = @namespaces.map do |namespace|
|
21
|
+
@current_constant = nil
|
22
|
+
|
23
|
+
if namespace.is_a? Module
|
24
|
+
@current_constant = namespace
|
25
|
+
else
|
26
|
+
namespace = namespace.to_s
|
27
|
+
@constant_loader.load namespace
|
28
|
+
end
|
29
|
+
|
30
|
+
@current_constant
|
31
|
+
end.uniq.to_a - [nil]
|
32
|
+
end
|
33
|
+
|
34
|
+
def log_failed_lookup string
|
35
|
+
EUSTON_LOG.warn "Couldn't find handler namespace: #{string}" if Object.const_defined?('EUSTON_LOG')
|
36
|
+
end
|
37
|
+
|
38
|
+
def map_namespaces_to_references
|
39
|
+
references = []
|
40
|
+
|
41
|
+
@namespaces.each do |namespace|
|
42
|
+
references.push *(namespace.constants.map do |constant|
|
43
|
+
reference = HandlerReference.new namespace, namespace.const_get(constant), constant
|
44
|
+
reference = nil unless @required_mixins.all? { |mixin| reference.handler.included_modules.include? mixin }
|
45
|
+
reference
|
46
|
+
end.to_a - [nil])
|
47
|
+
end
|
48
|
+
|
49
|
+
references
|
50
|
+
end
|
51
|
+
|
52
|
+
def store_found_constant constant
|
53
|
+
@current_constant = constant if constant.is_a?(Module)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -16,7 +16,6 @@ module Euston
|
|
16
16
|
include Hollywood
|
17
17
|
|
18
18
|
def initialize channel, exchange_name
|
19
|
-
|
20
19
|
@channel = channel
|
21
20
|
@exchange = get_exchange channel, exchange_name
|
22
21
|
@read_model = Euston::RabbitMq::ReadModel::MessageBuffer.send exchange_name
|
@@ -65,4 +64,4 @@ module Euston
|
|
65
64
|
end
|
66
65
|
end
|
67
66
|
end
|
68
|
-
end
|
67
|
+
end
|
@@ -27,6 +27,11 @@ module Euston
|
|
27
27
|
'json' => ::ActiveSupport::JSON.encode(message) }, :safe => { :fsync => true })
|
28
28
|
end
|
29
29
|
|
30
|
+
def find_next_message
|
31
|
+
query = { 'next_attempt' => { '$lte' => Time.now.to_f } }
|
32
|
+
@collection.find_one(query)
|
33
|
+
end
|
34
|
+
|
30
35
|
def find_due_messages
|
31
36
|
query = { 'next_attempt' => { '$lte' => Time.now.to_f } }
|
32
37
|
order = [ 'next_attempt', Mongo::ASCENDING ]
|
@@ -40,7 +45,7 @@ module Euston
|
|
40
45
|
|
41
46
|
def set_next_attempt message
|
42
47
|
@collection.update({ '_id' => message['_id'] },
|
43
|
-
{ '$set' => { 'next_attempt' =>
|
48
|
+
{ '$set' => { 'next_attempt' => Time.now.to_f + 10 } }, :safe => { :fsync => true })
|
44
49
|
end
|
45
50
|
|
46
51
|
def remove_published_message id
|
@@ -49,4 +54,4 @@ module Euston
|
|
49
54
|
end
|
50
55
|
end
|
51
56
|
end
|
52
|
-
end
|
57
|
+
end
|
@@ -1,47 +1,16 @@
|
|
1
1
|
module Euston
|
2
2
|
module RabbitMq
|
3
|
-
class
|
4
|
-
include
|
3
|
+
class RetriableSubscription
|
4
|
+
include Hollywood
|
5
5
|
include Euston::RabbitMq::Queues
|
6
|
+
include Euston::RabbitMq::Exchanges
|
6
7
|
|
7
|
-
def initialize channel
|
8
|
+
def initialize channel, queue_name
|
8
9
|
@channel = channel
|
9
|
-
@
|
10
|
-
:events => get_exchange(@channel, :events) }
|
11
|
-
@namespaces = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def add_namespace namespace
|
15
|
-
@namespaces << namespace
|
16
|
-
end
|
17
|
-
|
18
|
-
def namespaced_handler_types
|
19
|
-
ret = []
|
20
|
-
@namespaces.each do |namespace|
|
21
|
-
namespace.constants.each do |handler_type|
|
22
|
-
ret << [namespace, handler_type]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
ret
|
26
|
-
end
|
27
|
-
|
28
|
-
def finalize_bindings
|
29
|
-
namespaced_handler_types.each do |namespace, handler_type|
|
30
|
-
bind_handler handler_type
|
31
|
-
end
|
10
|
+
@queue_name = queue_name
|
32
11
|
end
|
33
12
|
|
34
|
-
|
35
|
-
|
36
|
-
def bind_handler handler_type
|
37
|
-
# virtual
|
38
|
-
end
|
39
|
-
|
40
|
-
def find_namespaces_containing_handler_type handler_type
|
41
|
-
@namespaces.select { |namespace| namespace.const_defined? handler_type }
|
42
|
-
end
|
43
|
-
|
44
|
-
def attach_queue_hook_listeners queue
|
13
|
+
def attach_queue_hook_listeners
|
45
14
|
queue.when(:message_decode_failed => method(:log_decode_failure),
|
46
15
|
:message_failed => method(:handle_failure),
|
47
16
|
:message_received => method(:call_handler))
|
@@ -49,8 +18,10 @@ module Euston
|
|
49
18
|
queue.safe_subscribe
|
50
19
|
end
|
51
20
|
|
21
|
+
private
|
22
|
+
|
52
23
|
def call_handler(message)
|
53
|
-
|
24
|
+
callback :message_received, message
|
54
25
|
end
|
55
26
|
|
56
27
|
def create_message_failed_message error, failed_message, amqp_header
|
@@ -80,19 +51,25 @@ module Euston
|
|
80
51
|
|
81
52
|
begin
|
82
53
|
if failures == 3
|
54
|
+
debug_message = "Message failed, out of retries"
|
55
|
+
|
83
56
|
message.delete :failures
|
84
57
|
message = create_message_failed_message error, message, amqp_header
|
85
58
|
|
86
59
|
options = { :key => 'events.message_failed' }
|
87
60
|
exchange = :events
|
88
61
|
else
|
62
|
+
debug_message = "Message failed, retrying"
|
63
|
+
|
89
64
|
options = { :key => amqp_header.method.routing_key }
|
90
65
|
exchange = amqp_header.method.routing_key.split('.').first.to_sym
|
91
66
|
end
|
92
67
|
|
93
68
|
options = default_publish_options.merge options
|
94
|
-
exchange = @
|
95
|
-
message =
|
69
|
+
exchange = get_exchange @channel, exchange
|
70
|
+
message = ActiveSupport::JSON.encode message
|
71
|
+
|
72
|
+
EUSTON_LOG.debug "#{debug_message}: #{message}"
|
96
73
|
|
97
74
|
exchange.publish message, options
|
98
75
|
|
@@ -110,6 +87,10 @@ module Euston
|
|
110
87
|
|
111
88
|
Safely.report! err
|
112
89
|
end
|
90
|
+
|
91
|
+
def queue
|
92
|
+
@queue ||= get_queue @channel, @queue_name
|
93
|
+
end
|
113
94
|
end
|
114
95
|
end
|
115
|
-
end
|
96
|
+
end
|
data/lib/euston-rabbitmq.rb
CHANGED
@@ -17,7 +17,9 @@ require 'hollywood'
|
|
17
17
|
require 'euston'
|
18
18
|
require 'euston-eventstore'
|
19
19
|
|
20
|
-
require_rel 'euston-rabbitmq'
|
20
|
+
require_rel 'euston-rabbitmq/exchanges.rb'
|
21
|
+
require_rel 'euston-rabbitmq/queues.rb'
|
22
|
+
require_rel 'euston-rabbitmq/**/*.rb'
|
21
23
|
|
22
24
|
module Euston
|
23
25
|
module RabbitMq
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
module ConstantLoaderTesting
|
4
|
+
module SubNamespace
|
5
|
+
class Foobar
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'constant loader' do
|
11
|
+
let(:loader) { Euston::RabbitMq::ConstantLoader.new }
|
12
|
+
let(:outcome) { { :hit => nil, :miss => nil} }
|
13
|
+
|
14
|
+
before { loader.when(:hit => ->(constant) { outcome[:hit] = constant }, :miss => ->{ outcome[:miss] = true }) }
|
15
|
+
|
16
|
+
subject do
|
17
|
+
loader.load constant_string
|
18
|
+
outcome
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a valid constant string' do
|
22
|
+
let(:constant_string) { 'ConstantLoaderTesting::SubNamespace::Foobar' }
|
23
|
+
|
24
|
+
its([:hit]) { should == ConstantLoaderTesting::SubNamespace::Foobar }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with a totally invalid constant string' do
|
28
|
+
let(:constant_string) { 'Something::Entirely::Made::Up' }
|
29
|
+
|
30
|
+
its([:miss]) { should == true }
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with a partially invalid constant string' do
|
34
|
+
let(:constant_string) { 'ConstantLoaderTesting::Missing' }
|
35
|
+
|
36
|
+
its([:miss]) { should == true }
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
module HandlerFinderTesting
|
4
|
+
module EmptyNamespace; end
|
5
|
+
module SuperSpecialMixin; end
|
6
|
+
|
7
|
+
module NonEmptyNamespace
|
8
|
+
class Handler1; end
|
9
|
+
class Handler2; end
|
10
|
+
|
11
|
+
class Handler3
|
12
|
+
include HandlerFinderTesting::SuperSpecialMixin
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'handler finder' do
|
18
|
+
let(:required_mixins) { [] }
|
19
|
+
let(:finder) { Euston::RabbitMq::HandlerFinder.new required_mixins }
|
20
|
+
|
21
|
+
before { finder.namespaces.push *namespaces }
|
22
|
+
subject { finder.find }
|
23
|
+
|
24
|
+
context 'no namespaces are provided' do
|
25
|
+
let(:namespaces) { [] }
|
26
|
+
|
27
|
+
it { should be_empty }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'a namespace is provided which contains no classes' do
|
31
|
+
let(:namespaces) { [HandlerFinderTesting::EmptyNamespace] }
|
32
|
+
|
33
|
+
it { should be_empty }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'a namespace is provided with contains some classes' do
|
37
|
+
let(:namespaces) { [HandlerFinderTesting::EmptyNamespace, 'HandlerFinderTesting::NonEmptyNamespace'] }
|
38
|
+
|
39
|
+
it { should have(3).items }
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'a specific mixin is required on each handler' do
|
43
|
+
let(:required_mixins) { [HandlerFinderTesting::SuperSpecialMixin] }
|
44
|
+
let(:namespaces) { [HandlerFinderTesting::EmptyNamespace, 'HandlerFinderTesting::NonEmptyNamespace'] }
|
45
|
+
|
46
|
+
it { should have(1).items }
|
47
|
+
end
|
48
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: euston-rabbitmq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-09-
|
13
|
+
date: 2011-09-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
17
|
-
requirement: &
|
17
|
+
requirement: &79361210 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: 3.0.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *79361210
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: euston
|
28
|
-
requirement: &
|
28
|
+
requirement: &79360880 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: 1.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *79360880
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: euston-eventstore
|
39
|
-
requirement: &
|
39
|
+
requirement: &79360360 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: 1.0.0
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *79360360
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: hash-keys
|
50
|
-
requirement: &
|
50
|
+
requirement: &79359860 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ~>
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: 1.0.0
|
56
56
|
type: :runtime
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *79359860
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: hollywood
|
61
|
-
requirement: &
|
61
|
+
requirement: &79359520 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ~>
|
@@ -66,10 +66,10 @@ dependencies:
|
|
66
66
|
version: 1.0.0
|
67
67
|
type: :runtime
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *79359520
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
71
|
name: require_all
|
72
|
-
requirement: &
|
72
|
+
requirement: &79359140 !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
@@ -77,10 +77,10 @@ dependencies:
|
|
77
77
|
version: 1.2.0
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
|
-
version_requirements: *
|
80
|
+
version_requirements: *79359140
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
82
|
name: robustthread
|
83
|
-
requirement: &
|
83
|
+
requirement: &79358710 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
85
85
|
requirements:
|
86
86
|
- - ~>
|
@@ -88,10 +88,10 @@ dependencies:
|
|
88
88
|
version: 0.5.2
|
89
89
|
type: :runtime
|
90
90
|
prerelease: false
|
91
|
-
version_requirements: *
|
91
|
+
version_requirements: *79358710
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: safely
|
94
|
-
requirement: &
|
94
|
+
requirement: &79358290 !ruby/object:Gem::Requirement
|
95
95
|
none: false
|
96
96
|
requirements:
|
97
97
|
- - ~>
|
@@ -99,10 +99,10 @@ dependencies:
|
|
99
99
|
version: 0.3.0
|
100
100
|
type: :runtime
|
101
101
|
prerelease: false
|
102
|
-
version_requirements: *
|
102
|
+
version_requirements: *79358290
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: amqp
|
105
|
-
requirement: &
|
105
|
+
requirement: &79357840 !ruby/object:Gem::Requirement
|
106
106
|
none: false
|
107
107
|
requirements:
|
108
108
|
- - ~>
|
@@ -110,10 +110,10 @@ dependencies:
|
|
110
110
|
version: 0.8.0
|
111
111
|
type: :runtime
|
112
112
|
prerelease: false
|
113
|
-
version_requirements: *
|
113
|
+
version_requirements: *79357840
|
114
114
|
- !ruby/object:Gem::Dependency
|
115
115
|
name: bson_ext
|
116
|
-
requirement: &
|
116
|
+
requirement: &79357520 !ruby/object:Gem::Requirement
|
117
117
|
none: false
|
118
118
|
requirements:
|
119
119
|
- - ~>
|
@@ -121,10 +121,10 @@ dependencies:
|
|
121
121
|
version: 1.3.1
|
122
122
|
type: :runtime
|
123
123
|
prerelease: false
|
124
|
-
version_requirements: *
|
124
|
+
version_requirements: *79357520
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: eventmachine
|
127
|
-
requirement: &
|
127
|
+
requirement: &79357270 !ruby/object:Gem::Requirement
|
128
128
|
none: false
|
129
129
|
requirements:
|
130
130
|
- - ~>
|
@@ -132,10 +132,10 @@ dependencies:
|
|
132
132
|
version: 0.12.10
|
133
133
|
type: :runtime
|
134
134
|
prerelease: false
|
135
|
-
version_requirements: *
|
135
|
+
version_requirements: *79357270
|
136
136
|
- !ruby/object:Gem::Dependency
|
137
137
|
name: mongo
|
138
|
-
requirement: &
|
138
|
+
requirement: &79356960 !ruby/object:Gem::Requirement
|
139
139
|
none: false
|
140
140
|
requirements:
|
141
141
|
- - ~>
|
@@ -143,10 +143,10 @@ dependencies:
|
|
143
143
|
version: 1.3.1
|
144
144
|
type: :runtime
|
145
145
|
prerelease: false
|
146
|
-
version_requirements: *
|
146
|
+
version_requirements: *79356960
|
147
147
|
- !ruby/object:Gem::Dependency
|
148
148
|
name: evented-spec
|
149
|
-
requirement: &
|
149
|
+
requirement: &79356660 !ruby/object:Gem::Requirement
|
150
150
|
none: false
|
151
151
|
requirements:
|
152
152
|
- - ~>
|
@@ -154,10 +154,10 @@ dependencies:
|
|
154
154
|
version: 0.9.0
|
155
155
|
type: :development
|
156
156
|
prerelease: false
|
157
|
-
version_requirements: *
|
157
|
+
version_requirements: *79356660
|
158
158
|
- !ruby/object:Gem::Dependency
|
159
159
|
name: awesome_print
|
160
|
-
requirement: &
|
160
|
+
requirement: &79356350 !ruby/object:Gem::Requirement
|
161
161
|
none: false
|
162
162
|
requirements:
|
163
163
|
- - ~>
|
@@ -165,10 +165,10 @@ dependencies:
|
|
165
165
|
version: 0.4.0
|
166
166
|
type: :development
|
167
167
|
prerelease: false
|
168
|
-
version_requirements: *
|
168
|
+
version_requirements: *79356350
|
169
169
|
- !ruby/object:Gem::Dependency
|
170
170
|
name: faker
|
171
|
-
requirement: &
|
171
|
+
requirement: &79355980 !ruby/object:Gem::Requirement
|
172
172
|
none: false
|
173
173
|
requirements:
|
174
174
|
- - ~>
|
@@ -176,10 +176,10 @@ dependencies:
|
|
176
176
|
version: 1.0.0
|
177
177
|
type: :development
|
178
178
|
prerelease: false
|
179
|
-
version_requirements: *
|
179
|
+
version_requirements: *79355980
|
180
180
|
- !ruby/object:Gem::Dependency
|
181
181
|
name: fuubar
|
182
|
-
requirement: &
|
182
|
+
requirement: &79355660 !ruby/object:Gem::Requirement
|
183
183
|
none: false
|
184
184
|
requirements:
|
185
185
|
- - ~>
|
@@ -187,10 +187,10 @@ dependencies:
|
|
187
187
|
version: 0.0.0
|
188
188
|
type: :development
|
189
189
|
prerelease: false
|
190
|
-
version_requirements: *
|
190
|
+
version_requirements: *79355660
|
191
191
|
- !ruby/object:Gem::Dependency
|
192
192
|
name: rspec
|
193
|
-
requirement: &
|
193
|
+
requirement: &79355170 !ruby/object:Gem::Requirement
|
194
194
|
none: false
|
195
195
|
requirements:
|
196
196
|
- - ~>
|
@@ -198,7 +198,7 @@ dependencies:
|
|
198
198
|
version: 2.6.0
|
199
199
|
type: :development
|
200
200
|
prerelease: false
|
201
|
-
version_requirements: *
|
201
|
+
version_requirements: *79355170
|
202
202
|
description: JRuby RabbitMq bindings
|
203
203
|
email:
|
204
204
|
- lee.m.henson@gmail.com
|
@@ -208,20 +208,19 @@ extensions: []
|
|
208
208
|
extra_rdoc_files: []
|
209
209
|
files:
|
210
210
|
- Gemfile
|
211
|
-
- Gemfile.lock
|
212
211
|
- Rakefile
|
213
212
|
- euston-rabbitmq.gemspec
|
214
213
|
- lib/euston-rabbitmq.rb
|
215
|
-
- lib/euston-rabbitmq/
|
216
|
-
- lib/euston-rabbitmq/
|
214
|
+
- lib/euston-rabbitmq/bindings/command_handler_binder.rb
|
215
|
+
- lib/euston-rabbitmq/bindings/event_handler_binder.rb
|
216
|
+
- lib/euston-rabbitmq/bindings/handler_binder.rb
|
217
217
|
- lib/euston-rabbitmq/command_handlers/retry_failed_message.rb
|
218
|
+
- lib/euston-rabbitmq/constant_loader.rb
|
218
219
|
- lib/euston-rabbitmq/errors.rb
|
219
|
-
- lib/euston-rabbitmq/event_handler_binding.rb
|
220
|
-
- lib/euston-rabbitmq/event_handler_bindings.rb
|
221
220
|
- lib/euston-rabbitmq/event_handlers/message_failure.rb
|
222
|
-
- lib/euston-rabbitmq/event_store_dispatcher.rb
|
223
221
|
- lib/euston-rabbitmq/exchanges.rb
|
224
|
-
- lib/euston-rabbitmq/
|
222
|
+
- lib/euston-rabbitmq/handler_finder.rb
|
223
|
+
- lib/euston-rabbitmq/handler_reference.rb
|
225
224
|
- lib/euston-rabbitmq/message_buffer.rb
|
226
225
|
- lib/euston-rabbitmq/message_logger.rb
|
227
226
|
- lib/euston-rabbitmq/queue.rb
|
@@ -229,10 +228,13 @@ files:
|
|
229
228
|
- lib/euston-rabbitmq/read_model/failed_message.rb
|
230
229
|
- lib/euston-rabbitmq/read_model/message_buffer.rb
|
231
230
|
- lib/euston-rabbitmq/read_model/message_log.rb
|
231
|
+
- lib/euston-rabbitmq/subscriptions/retriable_subscription.rb
|
232
232
|
- lib/euston-rabbitmq/version.rb
|
233
233
|
- spec/command_buffer_spec.rb
|
234
|
+
- spec/constant_loader_spec.rb
|
234
235
|
- spec/event_buffer_spec.rb
|
235
236
|
- spec/exchange_declaration_spec.rb
|
237
|
+
- spec/handler_finder_spec.rb
|
236
238
|
- spec/message_failure_spec.rb
|
237
239
|
- spec/mt_safe_queue_subscription_spec.rb
|
238
240
|
- spec/safe_queue_subscription_spec.rb
|
data/Gemfile.lock
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
euston-rabbitmq (1.0.0)
|
5
|
-
activesupport (~> 3.0.0)
|
6
|
-
amqp (~> 0.8.0)
|
7
|
-
bson_ext (~> 1.3.1)
|
8
|
-
euston (~> 1.0.0)
|
9
|
-
euston-eventstore (~> 1.0.0)
|
10
|
-
eventmachine (~> 0.12.10)
|
11
|
-
hash-keys (~> 1.0.0)
|
12
|
-
hollywood (~> 1.0.0)
|
13
|
-
mongo (~> 1.3.1)
|
14
|
-
require_all (~> 1.2.0)
|
15
|
-
robustthread (~> 0.5.2)
|
16
|
-
safely (~> 0.3.0)
|
17
|
-
|
18
|
-
GEM
|
19
|
-
remote: http://rubygems.org/
|
20
|
-
specs:
|
21
|
-
activesupport (3.0.10)
|
22
|
-
amq-client (0.8.3)
|
23
|
-
amq-protocol (>= 0.8.0)
|
24
|
-
eventmachine
|
25
|
-
amq-protocol (0.8.1)
|
26
|
-
amqp (0.8.0)
|
27
|
-
amq-client (~> 0.8.3)
|
28
|
-
amq-protocol (~> 0.8.0)
|
29
|
-
eventmachine
|
30
|
-
awesome_print (0.4.0)
|
31
|
-
bson (1.3.1)
|
32
|
-
bson (1.3.1-java)
|
33
|
-
bson_ext (1.3.1)
|
34
|
-
diff-lcs (1.1.3)
|
35
|
-
euston (1.0.0)
|
36
|
-
activesupport (~> 3.0.9)
|
37
|
-
euston-eventstore (~> 1.0.0)
|
38
|
-
require_all (~> 1.2.0)
|
39
|
-
euston-eventstore (1.0.4)
|
40
|
-
activesupport (~> 3.0.9)
|
41
|
-
bson_ext (~> 1.3.1)
|
42
|
-
hash-keys (~> 1.0.0)
|
43
|
-
json (~> 1.5.0)
|
44
|
-
mongo (~> 1.3.1)
|
45
|
-
require_all (~> 1.2.0)
|
46
|
-
uuid (~> 2.3.0)
|
47
|
-
euston-eventstore (1.0.4-java)
|
48
|
-
activesupport (~> 3.0.9)
|
49
|
-
hash-keys (~> 1.0.0)
|
50
|
-
jmongo (~> 1.0.0)
|
51
|
-
json-jruby (~> 1.5.0)
|
52
|
-
require_all (~> 1.2.0)
|
53
|
-
uuid (~> 2.3.0)
|
54
|
-
evented-spec (0.9.0)
|
55
|
-
eventmachine (0.12.10)
|
56
|
-
eventmachine (0.12.10-java)
|
57
|
-
faker (1.0.0)
|
58
|
-
i18n (~> 0.4)
|
59
|
-
fuubar (0.0.6)
|
60
|
-
rspec (~> 2.0)
|
61
|
-
rspec-instafail (~> 0.1.8)
|
62
|
-
ruby-progressbar (~> 0.0.10)
|
63
|
-
hash-keys (1.0.0)
|
64
|
-
hollywood (1.0.0)
|
65
|
-
i18n (0.6.0)
|
66
|
-
jmongo (1.0.3)
|
67
|
-
require_all (~> 1.2)
|
68
|
-
json (1.5.0)
|
69
|
-
json (1.5.0-java)
|
70
|
-
json-jruby (1.5.0-java)
|
71
|
-
json (= 1.5.0)
|
72
|
-
macaddr (1.4.0)
|
73
|
-
systemu (~> 2.2.0)
|
74
|
-
mongo (1.3.1)
|
75
|
-
bson (>= 1.3.1)
|
76
|
-
require_all (1.2.0)
|
77
|
-
robustthread (0.5.2)
|
78
|
-
rspec (2.6.0)
|
79
|
-
rspec-core (~> 2.6.0)
|
80
|
-
rspec-expectations (~> 2.6.0)
|
81
|
-
rspec-mocks (~> 2.6.0)
|
82
|
-
rspec-core (2.6.4)
|
83
|
-
rspec-expectations (2.6.0)
|
84
|
-
diff-lcs (~> 1.1.2)
|
85
|
-
rspec-instafail (0.1.8)
|
86
|
-
rspec-mocks (2.6.0)
|
87
|
-
ruby-progressbar (0.0.10)
|
88
|
-
safely (0.3.0)
|
89
|
-
systemu (2.2.0)
|
90
|
-
uuid (2.3.4)
|
91
|
-
macaddr (~> 1.0)
|
92
|
-
|
93
|
-
PLATFORMS
|
94
|
-
java
|
95
|
-
ruby
|
96
|
-
|
97
|
-
DEPENDENCIES
|
98
|
-
awesome_print (~> 0.4.0)
|
99
|
-
euston-rabbitmq!
|
100
|
-
evented-spec (~> 0.9.0)
|
101
|
-
faker (~> 1.0.0)
|
102
|
-
fuubar (~> 0.0.0)
|
103
|
-
rspec (~> 2.6.0)
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Euston
|
2
|
-
module RabbitMq
|
3
|
-
class BufferedMessageDispatcher
|
4
|
-
class << self
|
5
|
-
def command_dispatcher channel
|
6
|
-
@command_dispatcher ||= BufferedMessageDispatcher.new(Euston::RabbitMq::MessageBuffer.commands_buffer channel)
|
7
|
-
end
|
8
|
-
|
9
|
-
def event_dispatcher channel
|
10
|
-
@event_dispatcher ||= BufferedMessageDispatcher.new(Euston::RabbitMq::MessageBuffer.events_buffer channel)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
include Euston::RabbitMq::Exchanges
|
15
|
-
|
16
|
-
def initialize buffer
|
17
|
-
@buffer = buffer
|
18
|
-
@buffer.when(:no_messages_were_due) { @sleep = true }
|
19
|
-
end
|
20
|
-
|
21
|
-
attr_writer :wait_time
|
22
|
-
|
23
|
-
def wait_time
|
24
|
-
@wait_time ||= 1
|
25
|
-
end
|
26
|
-
|
27
|
-
def stop
|
28
|
-
@stop = true
|
29
|
-
end
|
30
|
-
|
31
|
-
def start
|
32
|
-
@stop = false
|
33
|
-
|
34
|
-
dispatch_loop = Proc.new do
|
35
|
-
@sleep = false
|
36
|
-
|
37
|
-
begin
|
38
|
-
@buffer.dispatch_due_messages
|
39
|
-
end while !@sleep
|
40
|
-
|
41
|
-
EM.add_timer(wait_time) { dispatch_loop.call } unless @stop
|
42
|
-
end
|
43
|
-
|
44
|
-
EM.add_timer(wait_time) { dispatch_loop.call }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Euston
|
2
|
-
module RabbitMq
|
3
|
-
class CommandHandlerBindings < HandlerBindings
|
4
|
-
def finalize_bindings
|
5
|
-
super
|
6
|
-
attach_queue_hook_listeners queue
|
7
|
-
end
|
8
|
-
|
9
|
-
protected
|
10
|
-
|
11
|
-
def bind_handler handler_type
|
12
|
-
queue.bind @exchanges[:commands], :routing_key => "commands.#{handler_type.to_s.underscore}"
|
13
|
-
end
|
14
|
-
|
15
|
-
def call_handler message
|
16
|
-
command_headers = CommandHeaders.from_hash(message[:headers]).freeze
|
17
|
-
command_body = message[:body].freeze
|
18
|
-
handler_type = command_headers.type.to_s.camelize.to_sym
|
19
|
-
find_namespaces_containing_handler_type(handler_type).each do |namespace|
|
20
|
-
handler = namespace.const_get handler_type
|
21
|
-
handler.new.send "__version__#{command_headers.version}", command_headers, command_body
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def queue
|
26
|
-
@queue ||= get_queue @channel, :command_handlers
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,114 +0,0 @@
|
|
1
|
-
module Euston
|
2
|
-
module RabbitMq
|
3
|
-
class EventHandlerBinding
|
4
|
-
include Euston::RabbitMq::Queues
|
5
|
-
include Euston::RabbitMq::Exchanges
|
6
|
-
|
7
|
-
PREFIX = '__event_handler__'
|
8
|
-
|
9
|
-
def initialize(channel, namespace, handler_type)
|
10
|
-
@channel, @namespace, @handler_type = channel, namespace, handler_type
|
11
|
-
|
12
|
-
name = @handler_type.to_s.underscore
|
13
|
-
@queue = get_queue(@channel, name)
|
14
|
-
instance_variable_set "@#{name}".to_sym, @queue
|
15
|
-
@handler_class = @namespace.const_get @handler_type
|
16
|
-
@exchange = get_exchange(@channel, :events)
|
17
|
-
end
|
18
|
-
|
19
|
-
def bind
|
20
|
-
bindable_methods.each do |method|
|
21
|
-
@queue.bind @exchange, :routing_key => "events.#{method}"
|
22
|
-
end
|
23
|
-
self
|
24
|
-
end
|
25
|
-
|
26
|
-
def listen
|
27
|
-
attach_queue_hook_listeners @queue
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def attach_queue_hook_listeners queue
|
33
|
-
queue.when(:message_decode_failed => method(:log_decode_failure),
|
34
|
-
:message_failed => method(:handle_failure),
|
35
|
-
:message_received => method(:call_handler))
|
36
|
-
|
37
|
-
queue.safe_subscribe
|
38
|
-
end
|
39
|
-
|
40
|
-
def call_handler(message)
|
41
|
-
event_headers = EventHeaders.from_hash message[:headers]
|
42
|
-
event_body = message[:body]
|
43
|
-
|
44
|
-
@handler_class.new.send "#{PREFIX}#{event_headers.type}__#{event_headers.version}", event_headers.freeze, event_body.freeze
|
45
|
-
end
|
46
|
-
|
47
|
-
def bindable_methods
|
48
|
-
methods = @handler_class.public_instance_methods(false)
|
49
|
-
methods = methods.select { |method| method.to_s.start_with? PREFIX }
|
50
|
-
methods = methods.map { |method| method.to_s[PREFIX.length, method.to_s.length - PREFIX.length] }
|
51
|
-
methods = methods.map { |method| method.split('__').first }
|
52
|
-
methods.uniq
|
53
|
-
end
|
54
|
-
|
55
|
-
def create_message_failed_message error, failed_message, amqp_header
|
56
|
-
{
|
57
|
-
:headers =>
|
58
|
-
{
|
59
|
-
:id => Euston.uuid.generate.to_s,
|
60
|
-
:type => :message_failed,
|
61
|
-
:version => 1,
|
62
|
-
:timestamp => Time.now.to_f
|
63
|
-
},
|
64
|
-
|
65
|
-
:body =>
|
66
|
-
{
|
67
|
-
:message => failed_message,
|
68
|
-
:routing_key => amqp_header.method.routing_key,
|
69
|
-
:error => error.message,
|
70
|
-
:backtrace => error.backtrace
|
71
|
-
}
|
72
|
-
}
|
73
|
-
end
|
74
|
-
|
75
|
-
def handle_failure message, error, amqp_header
|
76
|
-
failures = message[:failures] || 0
|
77
|
-
failures = failures + 1
|
78
|
-
message[:failures] = failures
|
79
|
-
|
80
|
-
begin
|
81
|
-
if failures == 3
|
82
|
-
message.delete :failures
|
83
|
-
message = create_message_failed_message error, message, amqp_header
|
84
|
-
|
85
|
-
options = { :key => 'events.message_failed' }
|
86
|
-
exchange_ref = :events
|
87
|
-
else
|
88
|
-
options = { :key => amqp_header.method.routing_key }
|
89
|
-
exchange_ref = amqp_header.method.routing_key.split('.').first.to_sym
|
90
|
-
end
|
91
|
-
|
92
|
-
options = default_publish_options.merge options
|
93
|
-
exchange = get_exchange(@channel, exchange_ref)
|
94
|
-
message = ::ActiveSupport::JSON.encode message
|
95
|
-
|
96
|
-
exchange.publish message, options
|
97
|
-
|
98
|
-
amqp_header.ack
|
99
|
-
rescue StandardError => e
|
100
|
-
amqp_header.reject :requeue => true
|
101
|
-
raise e
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def log_decode_failure message, error
|
106
|
-
text = "A handler queue subscription failed. [Error] #{error.message} [Payload] #{message}"
|
107
|
-
err = Euston::RabbitMq::MessageDecodeFailedError.new text
|
108
|
-
err.set_backtrace error.backtrace
|
109
|
-
|
110
|
-
Safely.report! err
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Euston
|
2
|
-
module RabbitMq
|
3
|
-
class EventHandlerBindings < HandlerBindings
|
4
|
-
PREFIX = '__event_handler__'
|
5
|
-
|
6
|
-
protected
|
7
|
-
|
8
|
-
def bind_handler handler_type
|
9
|
-
name = handler_type.to_s.underscore
|
10
|
-
queue = get_queue @channel, name
|
11
|
-
instance_variable_set "@#{name}".to_sym, queue
|
12
|
-
|
13
|
-
namespace = find_namespaces_containing_handler_type(handler_type).first
|
14
|
-
handler_class = namespace.const_get handler_type
|
15
|
-
methods = handler_class.public_instance_methods(false)
|
16
|
-
methods = methods.select { |method| method.to_s.start_with? PREFIX }
|
17
|
-
methods = methods.map { |method| method.to_s[PREFIX.length, method.to_s.length - PREFIX.length] }
|
18
|
-
methods = methods.map { |method| method.split('__').first }
|
19
|
-
methods.uniq.each { |method| queue.bind @exchanges[:events], :routing_key => "events.#{method}" }
|
20
|
-
|
21
|
-
attach_queue_hook_listeners queue do |message|
|
22
|
-
event_headers = EventHeaders.from_hash message[:headers]
|
23
|
-
event_body = message[:body]
|
24
|
-
|
25
|
-
handler_class.new.send "#{PREFIX}#{event_headers.type}__#{event_headers.version}", event_headers.freeze, event_body.freeze
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Euston
|
2
|
-
module RabbitMq
|
3
|
-
class EventStoreDispatcher
|
4
|
-
def initialize channel
|
5
|
-
@channel = channel
|
6
|
-
@event_buffer = Euston::RabbitMq::MessageBuffer.events_buffer channel
|
7
|
-
@event_store = Euston::RabbitMq.event_store
|
8
|
-
end
|
9
|
-
|
10
|
-
attr_writer :wait_time
|
11
|
-
|
12
|
-
def wait_time
|
13
|
-
@wait_time ||= 1
|
14
|
-
end
|
15
|
-
|
16
|
-
def stop
|
17
|
-
@stop = true
|
18
|
-
end
|
19
|
-
|
20
|
-
def start
|
21
|
-
@stop = false
|
22
|
-
|
23
|
-
dispatch_loop = Proc.new do
|
24
|
-
begin
|
25
|
-
begin
|
26
|
-
commits = @event_store.get_undispatched_commits
|
27
|
-
|
28
|
-
commits.each do |commit|
|
29
|
-
commit.events.each { |event| @event_buffer.push event.to_hash }
|
30
|
-
|
31
|
-
@event_store.mark_commit_as_dispatched commit
|
32
|
-
end
|
33
|
-
end while !commits.empty?
|
34
|
-
rescue StandardError => e
|
35
|
-
DaemonKit::logger.error "#{e}\n#{e.backtrace}"
|
36
|
-
end
|
37
|
-
|
38
|
-
EM.add_timer(wait_time) { dispatch_loop.call } unless @stop
|
39
|
-
end
|
40
|
-
|
41
|
-
EM.add_timer(wait_time) { dispatch_loop.call }
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|