euston-rabbitmq 1.0.0-java → 1.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +5 -32
- data/euston-rabbitmq.gemspec +10 -7
- 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 +42 -37
- 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/Gemfile.lock
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
euston-rabbitmq (1.0.0)
|
4
|
+
euston-rabbitmq (1.0.0-java)
|
5
5
|
activesupport (~> 3.0.0)
|
6
|
-
amqp (~> 0.8.0)
|
7
|
-
bson_ext (~> 1.3.1)
|
8
6
|
euston (~> 1.0.0)
|
9
7
|
euston-eventstore (~> 1.0.0)
|
10
|
-
eventmachine (~> 0.12.10)
|
11
8
|
hash-keys (~> 1.0.0)
|
12
9
|
hollywood (~> 1.0.0)
|
13
|
-
|
10
|
+
jessica (~> 1.0.0)
|
11
|
+
jmongo (~> 1.0.0)
|
14
12
|
require_all (~> 1.2.0)
|
15
13
|
robustthread (~> 0.5.2)
|
16
14
|
safely (~> 0.3.0)
|
@@ -19,31 +17,12 @@ GEM
|
|
19
17
|
remote: http://rubygems.org/
|
20
18
|
specs:
|
21
19
|
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
20
|
awesome_print (0.4.0)
|
31
|
-
bson (1.3.1)
|
32
|
-
bson (1.3.1-java)
|
33
|
-
bson_ext (1.3.1)
|
34
21
|
diff-lcs (1.1.3)
|
35
22
|
euston (1.0.0)
|
36
23
|
activesupport (~> 3.0.9)
|
37
24
|
euston-eventstore (~> 1.0.0)
|
38
25
|
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
26
|
euston-eventstore (1.0.4-java)
|
48
27
|
activesupport (~> 3.0.9)
|
49
28
|
hash-keys (~> 1.0.0)
|
@@ -51,9 +30,6 @@ GEM
|
|
51
30
|
json-jruby (~> 1.5.0)
|
52
31
|
require_all (~> 1.2.0)
|
53
32
|
uuid (~> 2.3.0)
|
54
|
-
evented-spec (0.9.0)
|
55
|
-
eventmachine (0.12.10)
|
56
|
-
eventmachine (0.12.10-java)
|
57
33
|
faker (1.0.0)
|
58
34
|
i18n (~> 0.4)
|
59
35
|
fuubar (0.0.6)
|
@@ -63,16 +39,15 @@ GEM
|
|
63
39
|
hash-keys (1.0.0)
|
64
40
|
hollywood (1.0.0)
|
65
41
|
i18n (0.6.0)
|
42
|
+
jessica (1.0.2-java)
|
43
|
+
require_all (~> 1.2.0)
|
66
44
|
jmongo (1.0.3)
|
67
45
|
require_all (~> 1.2)
|
68
|
-
json (1.5.0)
|
69
46
|
json (1.5.0-java)
|
70
47
|
json-jruby (1.5.0-java)
|
71
48
|
json (= 1.5.0)
|
72
49
|
macaddr (1.4.0)
|
73
50
|
systemu (~> 2.2.0)
|
74
|
-
mongo (1.3.1)
|
75
|
-
bson (>= 1.3.1)
|
76
51
|
require_all (1.2.0)
|
77
52
|
robustthread (0.5.2)
|
78
53
|
rspec (2.6.0)
|
@@ -92,12 +67,10 @@ GEM
|
|
92
67
|
|
93
68
|
PLATFORMS
|
94
69
|
java
|
95
|
-
ruby
|
96
70
|
|
97
71
|
DEPENDENCIES
|
98
72
|
awesome_print (~> 0.4.0)
|
99
73
|
euston-rabbitmq!
|
100
|
-
evented-spec (~> 0.9.0)
|
101
74
|
faker (~> 1.0.0)
|
102
75
|
fuubar (~> 0.0.0)
|
103
76
|
rspec (~> 2.6.0)
|
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']
|
@@ -15,16 +15,16 @@ Gem::Specification.new do |s|
|
|
15
15
|
Rakefile
|
16
16
|
euston-rabbitmq.gemspec
|
17
17
|
lib/euston-rabbitmq.rb
|
18
|
-
lib/euston-rabbitmq/
|
19
|
-
lib/euston-rabbitmq/
|
18
|
+
lib/euston-rabbitmq/bindings/command_handler_binder.rb
|
19
|
+
lib/euston-rabbitmq/bindings/event_handler_binder.rb
|
20
|
+
lib/euston-rabbitmq/bindings/handler_binder.rb
|
20
21
|
lib/euston-rabbitmq/command_handlers/retry_failed_message.rb
|
22
|
+
lib/euston-rabbitmq/constant_loader.rb
|
21
23
|
lib/euston-rabbitmq/errors.rb
|
22
|
-
lib/euston-rabbitmq/event_handler_binding.rb
|
23
|
-
lib/euston-rabbitmq/event_handler_bindings.rb
|
24
24
|
lib/euston-rabbitmq/event_handlers/message_failure.rb
|
25
|
-
lib/euston-rabbitmq/event_store_dispatcher.rb
|
26
25
|
lib/euston-rabbitmq/exchanges.rb
|
27
|
-
lib/euston-rabbitmq/
|
26
|
+
lib/euston-rabbitmq/handler_finder.rb
|
27
|
+
lib/euston-rabbitmq/handler_reference.rb
|
28
28
|
lib/euston-rabbitmq/message_buffer.rb
|
29
29
|
lib/euston-rabbitmq/message_logger.rb
|
30
30
|
lib/euston-rabbitmq/queue.rb
|
@@ -32,10 +32,13 @@ Gem::Specification.new do |s|
|
|
32
32
|
lib/euston-rabbitmq/read_model/failed_message.rb
|
33
33
|
lib/euston-rabbitmq/read_model/message_buffer.rb
|
34
34
|
lib/euston-rabbitmq/read_model/message_log.rb
|
35
|
+
lib/euston-rabbitmq/subscriptions/retriable_subscription.rb
|
35
36
|
lib/euston-rabbitmq/version.rb
|
36
37
|
spec/command_buffer_spec.rb
|
38
|
+
spec/constant_loader_spec.rb
|
37
39
|
spec/event_buffer_spec.rb
|
38
40
|
spec/exchange_declaration_spec.rb
|
41
|
+
spec/handler_finder_spec.rb
|
39
42
|
spec/message_failure_spec.rb
|
40
43
|
spec/mt_safe_queue_subscription_spec.rb
|
41
44
|
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
@@ -2,7 +2,7 @@
|
|
2
2
|
name: euston-rabbitmq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.0.
|
5
|
+
version: 1.0.1
|
6
6
|
platform: java
|
7
7
|
authors:
|
8
8
|
- Lee Henson
|
@@ -10,160 +10,161 @@ 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 +01:00
|
14
|
+
default_executable:
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: activesupport
|
17
|
-
version_requirements: &
|
18
|
+
version_requirements: &2158 !ruby/object:Gem::Requirement
|
18
19
|
requirements:
|
19
20
|
- - ~>
|
20
21
|
- !ruby/object:Gem::Version
|
21
22
|
version: 3.0.0
|
22
23
|
none: false
|
23
|
-
requirement: *
|
24
|
+
requirement: *2158
|
24
25
|
prerelease: false
|
25
26
|
type: :runtime
|
26
27
|
- !ruby/object:Gem::Dependency
|
27
28
|
name: euston
|
28
|
-
version_requirements: &
|
29
|
+
version_requirements: &2176 !ruby/object:Gem::Requirement
|
29
30
|
requirements:
|
30
31
|
- - ~>
|
31
32
|
- !ruby/object:Gem::Version
|
32
33
|
version: 1.0.0
|
33
34
|
none: false
|
34
|
-
requirement: *
|
35
|
+
requirement: *2176
|
35
36
|
prerelease: false
|
36
37
|
type: :runtime
|
37
38
|
- !ruby/object:Gem::Dependency
|
38
39
|
name: euston-eventstore
|
39
|
-
version_requirements: &
|
40
|
+
version_requirements: &2192 !ruby/object:Gem::Requirement
|
40
41
|
requirements:
|
41
42
|
- - ~>
|
42
43
|
- !ruby/object:Gem::Version
|
43
44
|
version: 1.0.0
|
44
45
|
none: false
|
45
|
-
requirement: *
|
46
|
+
requirement: *2192
|
46
47
|
prerelease: false
|
47
48
|
type: :runtime
|
48
49
|
- !ruby/object:Gem::Dependency
|
49
50
|
name: hash-keys
|
50
|
-
version_requirements: &
|
51
|
+
version_requirements: &2208 !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
53
|
- - ~>
|
53
54
|
- !ruby/object:Gem::Version
|
54
55
|
version: 1.0.0
|
55
56
|
none: false
|
56
|
-
requirement: *
|
57
|
+
requirement: *2208
|
57
58
|
prerelease: false
|
58
59
|
type: :runtime
|
59
60
|
- !ruby/object:Gem::Dependency
|
60
61
|
name: hollywood
|
61
|
-
version_requirements: &
|
62
|
+
version_requirements: &2224 !ruby/object:Gem::Requirement
|
62
63
|
requirements:
|
63
64
|
- - ~>
|
64
65
|
- !ruby/object:Gem::Version
|
65
66
|
version: 1.0.0
|
66
67
|
none: false
|
67
|
-
requirement: *
|
68
|
+
requirement: *2224
|
68
69
|
prerelease: false
|
69
70
|
type: :runtime
|
70
71
|
- !ruby/object:Gem::Dependency
|
71
72
|
name: require_all
|
72
|
-
version_requirements: &
|
73
|
+
version_requirements: &2240 !ruby/object:Gem::Requirement
|
73
74
|
requirements:
|
74
75
|
- - ~>
|
75
76
|
- !ruby/object:Gem::Version
|
76
77
|
version: 1.2.0
|
77
78
|
none: false
|
78
|
-
requirement: *
|
79
|
+
requirement: *2240
|
79
80
|
prerelease: false
|
80
81
|
type: :runtime
|
81
82
|
- !ruby/object:Gem::Dependency
|
82
83
|
name: robustthread
|
83
|
-
version_requirements: &
|
84
|
+
version_requirements: &2256 !ruby/object:Gem::Requirement
|
84
85
|
requirements:
|
85
86
|
- - ~>
|
86
87
|
- !ruby/object:Gem::Version
|
87
88
|
version: 0.5.2
|
88
89
|
none: false
|
89
|
-
requirement: *
|
90
|
+
requirement: *2256
|
90
91
|
prerelease: false
|
91
92
|
type: :runtime
|
92
93
|
- !ruby/object:Gem::Dependency
|
93
94
|
name: safely
|
94
|
-
version_requirements: &
|
95
|
+
version_requirements: &2272 !ruby/object:Gem::Requirement
|
95
96
|
requirements:
|
96
97
|
- - ~>
|
97
98
|
- !ruby/object:Gem::Version
|
98
99
|
version: 0.3.0
|
99
100
|
none: false
|
100
|
-
requirement: *
|
101
|
+
requirement: *2272
|
101
102
|
prerelease: false
|
102
103
|
type: :runtime
|
103
104
|
- !ruby/object:Gem::Dependency
|
104
105
|
name: jmongo
|
105
|
-
version_requirements: &
|
106
|
+
version_requirements: &2288 !ruby/object:Gem::Requirement
|
106
107
|
requirements:
|
107
108
|
- - ~>
|
108
109
|
- !ruby/object:Gem::Version
|
109
110
|
version: 1.0.0
|
110
111
|
none: false
|
111
|
-
requirement: *
|
112
|
+
requirement: *2288
|
112
113
|
prerelease: false
|
113
114
|
type: :runtime
|
114
115
|
- !ruby/object:Gem::Dependency
|
115
116
|
name: jessica
|
116
|
-
version_requirements: &
|
117
|
+
version_requirements: &2304 !ruby/object:Gem::Requirement
|
117
118
|
requirements:
|
118
119
|
- - ~>
|
119
120
|
- !ruby/object:Gem::Version
|
120
121
|
version: 1.0.0
|
121
122
|
none: false
|
122
|
-
requirement: *
|
123
|
+
requirement: *2304
|
123
124
|
prerelease: false
|
124
125
|
type: :runtime
|
125
126
|
- !ruby/object:Gem::Dependency
|
126
127
|
name: awesome_print
|
127
|
-
version_requirements: &
|
128
|
+
version_requirements: &2320 !ruby/object:Gem::Requirement
|
128
129
|
requirements:
|
129
130
|
- - ~>
|
130
131
|
- !ruby/object:Gem::Version
|
131
132
|
version: 0.4.0
|
132
133
|
none: false
|
133
|
-
requirement: *
|
134
|
+
requirement: *2320
|
134
135
|
prerelease: false
|
135
136
|
type: :development
|
136
137
|
- !ruby/object:Gem::Dependency
|
137
138
|
name: faker
|
138
|
-
version_requirements: &
|
139
|
+
version_requirements: &2338 !ruby/object:Gem::Requirement
|
139
140
|
requirements:
|
140
141
|
- - ~>
|
141
142
|
- !ruby/object:Gem::Version
|
142
143
|
version: 1.0.0
|
143
144
|
none: false
|
144
|
-
requirement: *
|
145
|
+
requirement: *2338
|
145
146
|
prerelease: false
|
146
147
|
type: :development
|
147
148
|
- !ruby/object:Gem::Dependency
|
148
149
|
name: fuubar
|
149
|
-
version_requirements: &
|
150
|
+
version_requirements: &2354 !ruby/object:Gem::Requirement
|
150
151
|
requirements:
|
151
152
|
- - ~>
|
152
153
|
- !ruby/object:Gem::Version
|
153
154
|
version: 0.0.0
|
154
155
|
none: false
|
155
|
-
requirement: *
|
156
|
+
requirement: *2354
|
156
157
|
prerelease: false
|
157
158
|
type: :development
|
158
159
|
- !ruby/object:Gem::Dependency
|
159
160
|
name: rspec
|
160
|
-
version_requirements: &
|
161
|
+
version_requirements: &2370 !ruby/object:Gem::Requirement
|
161
162
|
requirements:
|
162
163
|
- - ~>
|
163
164
|
- !ruby/object:Gem::Version
|
164
165
|
version: 2.6.0
|
165
166
|
none: false
|
166
|
-
requirement: *
|
167
|
+
requirement: *2370
|
167
168
|
prerelease: false
|
168
169
|
type: :development
|
169
170
|
description: JRuby RabbitMq bindings
|
@@ -179,16 +180,16 @@ files:
|
|
179
180
|
- Rakefile
|
180
181
|
- euston-rabbitmq.gemspec
|
181
182
|
- lib/euston-rabbitmq.rb
|
182
|
-
- lib/euston-rabbitmq/
|
183
|
-
- lib/euston-rabbitmq/
|
183
|
+
- lib/euston-rabbitmq/bindings/command_handler_binder.rb
|
184
|
+
- lib/euston-rabbitmq/bindings/event_handler_binder.rb
|
185
|
+
- lib/euston-rabbitmq/bindings/handler_binder.rb
|
184
186
|
- lib/euston-rabbitmq/command_handlers/retry_failed_message.rb
|
187
|
+
- lib/euston-rabbitmq/constant_loader.rb
|
185
188
|
- lib/euston-rabbitmq/errors.rb
|
186
|
-
- lib/euston-rabbitmq/event_handler_binding.rb
|
187
|
-
- lib/euston-rabbitmq/event_handler_bindings.rb
|
188
189
|
- lib/euston-rabbitmq/event_handlers/message_failure.rb
|
189
|
-
- lib/euston-rabbitmq/event_store_dispatcher.rb
|
190
190
|
- lib/euston-rabbitmq/exchanges.rb
|
191
|
-
- lib/euston-rabbitmq/
|
191
|
+
- lib/euston-rabbitmq/handler_finder.rb
|
192
|
+
- lib/euston-rabbitmq/handler_reference.rb
|
192
193
|
- lib/euston-rabbitmq/message_buffer.rb
|
193
194
|
- lib/euston-rabbitmq/message_logger.rb
|
194
195
|
- lib/euston-rabbitmq/queue.rb
|
@@ -196,15 +197,19 @@ files:
|
|
196
197
|
- lib/euston-rabbitmq/read_model/failed_message.rb
|
197
198
|
- lib/euston-rabbitmq/read_model/message_buffer.rb
|
198
199
|
- lib/euston-rabbitmq/read_model/message_log.rb
|
200
|
+
- lib/euston-rabbitmq/subscriptions/retriable_subscription.rb
|
199
201
|
- lib/euston-rabbitmq/version.rb
|
200
202
|
- spec/command_buffer_spec.rb
|
203
|
+
- spec/constant_loader_spec.rb
|
201
204
|
- spec/event_buffer_spec.rb
|
202
205
|
- spec/exchange_declaration_spec.rb
|
206
|
+
- spec/handler_finder_spec.rb
|
203
207
|
- spec/message_failure_spec.rb
|
204
208
|
- spec/mt_safe_queue_subscription_spec.rb
|
205
209
|
- spec/safe_queue_subscription_spec.rb
|
206
210
|
- spec/spec_helper.rb
|
207
211
|
- spec/support/factories.rb
|
212
|
+
has_rdoc: true
|
208
213
|
homepage: http://github.com/leemhenson/euston-rabbitmq
|
209
214
|
licenses: []
|
210
215
|
post_install_message:
|
@@ -225,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
230
|
none: false
|
226
231
|
requirements: []
|
227
232
|
rubyforge_project:
|
228
|
-
rubygems_version: 1.
|
233
|
+
rubygems_version: 1.5.1
|
229
234
|
signing_key:
|
230
235
|
specification_version: 3
|
231
236
|
summary: RabbitMq bindings for Euston.
|
@@ -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
|