euston-daemons 1.1.0-java → 1.2.0-java
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/Gemfile +1 -0
- data/euston-daemons.gemspec +27 -52
- data/lib/euston-daemons/euston/daemon.rb +7 -1
- data/lib/euston-daemons/euston/daemon_component.rb +9 -49
- data/lib/euston-daemons/euston/daemon_component_host.rb +66 -0
- data/lib/euston-daemons/euston/daemon_environment.rb +10 -5
- data/lib/euston-daemons/euston/exceptions.rb +9 -0
- data/lib/euston-daemons/euston/stopwatch.rb +15 -0
- data/lib/euston-daemons/pipeline/config/environment.rb +74 -0
- data/lib/euston-daemons/pipeline/lib/command_logger/component.rb +54 -0
- data/lib/euston-daemons/pipeline/lib/command_logger/log.rb +31 -0
- data/lib/euston-daemons/pipeline/lib/command_processor/component.rb +50 -0
- data/lib/euston-daemons/pipeline/lib/command_processor/default_handlers/retry_failed_message.rb +34 -0
- data/lib/euston-daemons/pipeline/lib/command_processor/failed_message.rb +36 -0
- data/lib/euston-daemons/pipeline/lib/daemon.rb +77 -0
- data/lib/euston-daemons/pipeline/lib/event_processor/component.rb +67 -0
- data/lib/euston-daemons/pipeline/lib/event_processor/default_handlers/message_failure.rb +30 -0
- data/lib/euston-daemons/pipeline/lib/event_store_dispatcher/component.rb +68 -0
- data/lib/euston-daemons/pipeline/lib/message_buffer/buffer.rb +85 -0
- data/lib/euston-daemons/pipeline/lib/message_buffer/component.rb +59 -0
- data/lib/euston-daemons/pipeline/lib/snapshotter/component.rb +48 -0
- data/lib/euston-daemons/pipeline/rake_task.rb +45 -0
- data/lib/euston-daemons/rake_task.rb +40 -19
- data/lib/euston-daemons/rake_tasks.rb +1 -3
- data/lib/euston-daemons/version.rb +1 -1
- data/lib/euston-daemons.rb +3 -1
- data/spec/daemons/{command_handler_spec.rb → command_processor_spec.rb} +3 -3
- data/spec/daemons/{event_handler_spec.rb → event_processor_spec.rb} +2 -2
- data/spec/daemons/{command_buffer_publisher_spec.rb → message_buffer_spec.rb} +19 -23
- data/spec/daemons/{snapshot_client_spec.rb → snapshotter_spec.rb} +3 -5
- data/spec/spec_helper.rb +23 -9
- data/spec/support/filters.rb +4 -5
- metadata +73 -88
- data/lib/euston-daemons/command_processor_daemon/config/environment.rb +0 -34
- data/lib/euston-daemons/command_processor_daemon/lib/clients/command_handler.rb +0 -37
- data/lib/euston-daemons/command_processor_daemon/lib/command_handlers/retry_failed_message.rb +0 -35
- data/lib/euston-daemons/command_processor_daemon/lib/daemon.rb +0 -22
- data/lib/euston-daemons/command_processor_daemon/lib/mongo_models/failed_message.rb +0 -34
- data/lib/euston-daemons/command_processor_daemon/rake_task.rb +0 -36
- data/lib/euston-daemons/euston/daemon_client.rb +0 -24
- data/lib/euston-daemons/event_processor_daemon/config/environment.rb +0 -36
- data/lib/euston-daemons/event_processor_daemon/lib/clients/event_handler.rb +0 -42
- data/lib/euston-daemons/event_processor_daemon/lib/daemon.rb +0 -24
- data/lib/euston-daemons/event_processor_daemon/lib/event_handlers/message_failure.rb +0 -27
- data/lib/euston-daemons/event_processor_daemon/rake_task.rb +0 -39
- data/lib/euston-daemons/message_buffer_daemon/config/environment.rb +0 -42
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_cleanup.rb +0 -9
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_publisher.rb +0 -9
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_logger.rb +0 -9
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/euston_exchange_accessors.rb +0 -15
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_cleanup.rb +0 -9
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_publisher.rb +0 -9
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_logger.rb +0 -9
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_store_dispatcher.rb +0 -25
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_cleanup.rb +0 -52
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_publisher.rb +0 -37
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_logger.rb +0 -45
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/mongo_model_accessors.rb +0 -21
- data/lib/euston-daemons/message_buffer_daemon/lib/daemon.rb +0 -17
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_buffer.rb +0 -11
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_log.rb +0 -11
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_buffer.rb +0 -11
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_log.rb +0 -11
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_buffer.rb +0 -57
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_log.rb +0 -29
- data/lib/euston-daemons/message_buffer_daemon/rake_task.rb +0 -32
- data/lib/euston-daemons/snapshot_daemon/lib/clients/snapshotter.rb +0 -43
- data/sample/Rakefile +0 -63
- data/sample/amqp_config.yml +0 -14
- data/sample/command_handlers.rb +0 -17
- data/sample/command_processor_daemon_config.yml +0 -9
- data/sample/event_handlers.rb +0 -21
- data/sample/event_processor_daemon_config.yml +0 -8
- data/sample/message_buffer_daemon_config.yml +0 -8
- data/sample/mongoid_config.yml +0 -13
- data/sample/pids/.placeholder +0 -0
data/Gemfile
CHANGED
|
@@ -4,3 +4,4 @@ gemspec
|
|
|
4
4
|
gem 'cranky', :git => 'https://github.com/leemhenson/cranky.git', :branch => 'hashes'
|
|
5
5
|
gem 'ffaker', :git => 'https://github.com/leemhenson/ffaker.git', :branch => 'countries'
|
|
6
6
|
gem 'safely', :git => 'https://github.com/leemhenson/safely.git', :branch => 'override_strategies'
|
|
7
|
+
gem 'hot_bunnies', :git => 'https://github.com/ruby-amqp/hot_bunnies.git'
|
data/euston-daemons.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'euston-daemons'
|
|
3
|
-
s.version = '1.
|
|
3
|
+
s.version = '1.2.0'
|
|
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,59 +15,33 @@ Gem::Specification.new do |s|
|
|
|
15
15
|
Rakefile
|
|
16
16
|
euston-daemons.gemspec
|
|
17
17
|
lib/euston-daemons.rb
|
|
18
|
-
lib/euston-daemons/command_processor_daemon/config/environment.rb
|
|
19
|
-
lib/euston-daemons/command_processor_daemon/lib/clients/command_handler.rb
|
|
20
|
-
lib/euston-daemons/command_processor_daemon/lib/command_handlers/retry_failed_message.rb
|
|
21
|
-
lib/euston-daemons/command_processor_daemon/lib/daemon.rb
|
|
22
|
-
lib/euston-daemons/command_processor_daemon/lib/mongo_models/failed_message.rb
|
|
23
|
-
lib/euston-daemons/command_processor_daemon/rake_task.rb
|
|
24
18
|
lib/euston-daemons/euston/daemon.rb
|
|
25
|
-
lib/euston-daemons/euston/daemon_client.rb
|
|
26
19
|
lib/euston-daemons/euston/daemon_component.rb
|
|
20
|
+
lib/euston-daemons/euston/daemon_component_host.rb
|
|
27
21
|
lib/euston-daemons/euston/daemon_environment.rb
|
|
28
|
-
lib/euston-daemons/
|
|
29
|
-
lib/euston-daemons/
|
|
30
|
-
lib/euston-daemons/
|
|
31
|
-
lib/euston-daemons/
|
|
32
|
-
lib/euston-daemons/
|
|
33
|
-
lib/euston-daemons/
|
|
34
|
-
lib/euston-daemons/
|
|
35
|
-
lib/euston-daemons/
|
|
36
|
-
lib/euston-daemons/
|
|
37
|
-
lib/euston-daemons/
|
|
38
|
-
lib/euston-daemons/
|
|
39
|
-
lib/euston-daemons/
|
|
40
|
-
lib/euston-daemons/
|
|
41
|
-
lib/euston-daemons/
|
|
42
|
-
lib/euston-daemons/
|
|
43
|
-
lib/euston-daemons/
|
|
44
|
-
lib/euston-daemons/message_buffer_daemon/lib/clients/message_logger.rb
|
|
45
|
-
lib/euston-daemons/message_buffer_daemon/lib/clients/mongo_model_accessors.rb
|
|
46
|
-
lib/euston-daemons/message_buffer_daemon/lib/daemon.rb
|
|
47
|
-
lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_buffer.rb
|
|
48
|
-
lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_log.rb
|
|
49
|
-
lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_buffer.rb
|
|
50
|
-
lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_log.rb
|
|
51
|
-
lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_buffer.rb
|
|
52
|
-
lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_log.rb
|
|
53
|
-
lib/euston-daemons/message_buffer_daemon/rake_task.rb
|
|
22
|
+
lib/euston-daemons/euston/exceptions.rb
|
|
23
|
+
lib/euston-daemons/euston/stopwatch.rb
|
|
24
|
+
lib/euston-daemons/pipeline/config/environment.rb
|
|
25
|
+
lib/euston-daemons/pipeline/lib/command_logger/component.rb
|
|
26
|
+
lib/euston-daemons/pipeline/lib/command_logger/log.rb
|
|
27
|
+
lib/euston-daemons/pipeline/lib/command_processor/component.rb
|
|
28
|
+
lib/euston-daemons/pipeline/lib/command_processor/default_handlers/retry_failed_message.rb
|
|
29
|
+
lib/euston-daemons/pipeline/lib/command_processor/failed_message.rb
|
|
30
|
+
lib/euston-daemons/pipeline/lib/daemon.rb
|
|
31
|
+
lib/euston-daemons/pipeline/lib/event_processor/component.rb
|
|
32
|
+
lib/euston-daemons/pipeline/lib/event_processor/default_handlers/message_failure.rb
|
|
33
|
+
lib/euston-daemons/pipeline/lib/event_store_dispatcher/component.rb
|
|
34
|
+
lib/euston-daemons/pipeline/lib/message_buffer/buffer.rb
|
|
35
|
+
lib/euston-daemons/pipeline/lib/message_buffer/component.rb
|
|
36
|
+
lib/euston-daemons/pipeline/lib/snapshotter/component.rb
|
|
37
|
+
lib/euston-daemons/pipeline/rake_task.rb
|
|
54
38
|
lib/euston-daemons/rake_task.rb
|
|
55
39
|
lib/euston-daemons/rake_tasks.rb
|
|
56
|
-
lib/euston-daemons/snapshot_daemon/lib/clients/snapshotter.rb
|
|
57
40
|
lib/euston-daemons/version.rb
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
sample/event_handlers.rb
|
|
63
|
-
sample/event_processor_daemon_config.yml
|
|
64
|
-
sample/message_buffer_daemon_config.yml
|
|
65
|
-
sample/mongoid_config.yml
|
|
66
|
-
sample/pids/.placeholder
|
|
67
|
-
spec/daemons/command_buffer_publisher_spec.rb
|
|
68
|
-
spec/daemons/command_handler_spec.rb
|
|
69
|
-
spec/daemons/event_handler_spec.rb
|
|
70
|
-
spec/daemons/snapshot_client_spec.rb
|
|
41
|
+
spec/daemons/command_processor_spec.rb
|
|
42
|
+
spec/daemons/event_processor_spec.rb
|
|
43
|
+
spec/daemons/message_buffer_spec.rb
|
|
44
|
+
spec/daemons/snapshotter_spec.rb
|
|
71
45
|
spec/spec_helper.rb
|
|
72
46
|
spec/support/factories/commands.rb
|
|
73
47
|
spec/support/factories/commit.rb
|
|
@@ -87,15 +61,16 @@ Gem::Specification.new do |s|
|
|
|
87
61
|
s.add_dependency 'activemodel', '~> 3.0.0'
|
|
88
62
|
s.add_dependency 'activesupport', '~> 3.0.0'
|
|
89
63
|
s.add_dependency 'erb-yaml', '~> 1.0.0'
|
|
90
|
-
s.add_dependency 'euston', '~> 1.
|
|
91
|
-
s.add_dependency 'euston-eventstore', '~> 1.
|
|
92
|
-
s.add_dependency 'euston-rabbitmq', '~> 1.
|
|
64
|
+
s.add_dependency 'euston', '~> 1.2.0'
|
|
65
|
+
s.add_dependency 'euston-eventstore', '~> 1.2.0'
|
|
66
|
+
s.add_dependency 'euston-rabbitmq', '~> 1.2.0'
|
|
93
67
|
s.add_dependency 'hollywood', '~> 1.0.0'
|
|
94
68
|
s.add_dependency 'i18n', '~> 0.5.0'
|
|
69
|
+
s.add_dependency 'macaddr', '~> 1.4.0'
|
|
95
70
|
s.add_dependency 'safely', '~> 0.3.0'
|
|
96
71
|
|
|
97
72
|
if RUBY_PLATFORM.to_s == 'java'
|
|
98
|
-
s.add_dependency '
|
|
73
|
+
s.add_dependency 'hot_bunnies', '~> 1.3.0.pre1'
|
|
99
74
|
s.add_dependency 'jmongo', '~> 1.1.0'
|
|
100
75
|
end
|
|
101
76
|
|
|
@@ -16,6 +16,7 @@ module Euston
|
|
|
16
16
|
start_components
|
|
17
17
|
wait_for_shutdown_event
|
|
18
18
|
stop_components
|
|
19
|
+
post_shutdown_cleanup
|
|
19
20
|
report_shutdown_reasons
|
|
20
21
|
end
|
|
21
22
|
|
|
@@ -26,10 +27,15 @@ module Euston
|
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
def register_component name, klass
|
|
29
|
-
component = Euston::
|
|
30
|
+
component = Euston::DaemonComponentHost.new @log, name, klass, self
|
|
30
31
|
component.when(:fatal_error_in_component => method(:shutdown))
|
|
31
32
|
|
|
32
33
|
@components << component
|
|
34
|
+
component
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def post_shutdown_cleanup
|
|
38
|
+
# virtual
|
|
33
39
|
end
|
|
34
40
|
|
|
35
41
|
def register_components
|
|
@@ -1,65 +1,25 @@
|
|
|
1
1
|
module Euston
|
|
2
2
|
class DaemonComponent
|
|
3
3
|
include Hollywood
|
|
4
|
+
include Daemons::Exceptions
|
|
4
5
|
|
|
5
|
-
def
|
|
6
|
-
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
attr_reader :name
|
|
10
|
-
|
|
11
|
-
def start
|
|
12
|
-
@thread = Thread.new do
|
|
13
|
-
while_thread_is_running do
|
|
14
|
-
begin
|
|
15
|
-
@client.run
|
|
16
|
-
rescue => e
|
|
17
|
-
Thread.current[:exception] = e
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
report_exceptions
|
|
21
|
-
end
|
|
22
|
-
end
|
|
6
|
+
def run
|
|
7
|
+
next_iteration unless stopped
|
|
23
8
|
end
|
|
24
9
|
|
|
25
10
|
def stop
|
|
26
|
-
@
|
|
27
|
-
@
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def thread_state
|
|
31
|
-
@thread.status
|
|
11
|
+
@stopped = true
|
|
12
|
+
@channel.close unless @channel.nil? || !@channel.respond_to?(:close)
|
|
32
13
|
end
|
|
33
14
|
|
|
34
15
|
private
|
|
35
16
|
|
|
36
|
-
def
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
unless exception.nil? || exception.to_s =~ /clean channel shutdown/
|
|
40
|
-
if exception.respond_to? :cause # its a serious (Java?) exception
|
|
41
|
-
Thread.current[:stop] = true
|
|
42
|
-
callback :fatal_error_in_component, exception
|
|
43
|
-
else
|
|
44
|
-
Safely.report! exception
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def thread_is_stopping?
|
|
50
|
-
Thread.current[:stop]
|
|
17
|
+
def next_iteration
|
|
18
|
+
# abstract
|
|
51
19
|
end
|
|
52
20
|
|
|
53
|
-
def
|
|
54
|
-
@
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def while_thread_is_running
|
|
58
|
-
until thread_is_stopping? do
|
|
59
|
-
yield
|
|
60
|
-
|
|
61
|
-
sleep wait_time
|
|
62
|
-
end
|
|
21
|
+
def stopped
|
|
22
|
+
@stopped ||= false
|
|
63
23
|
end
|
|
64
24
|
end
|
|
65
25
|
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
class DaemonComponentHost
|
|
3
|
+
include Hollywood
|
|
4
|
+
include Daemons::Exceptions
|
|
5
|
+
|
|
6
|
+
def initialize logger, name, client, owner
|
|
7
|
+
@log, @name, @client, @owner = logger, name, client, owner
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
attr_reader :name
|
|
11
|
+
attr_writer :wait_time
|
|
12
|
+
|
|
13
|
+
def start
|
|
14
|
+
@thread = Thread.new do
|
|
15
|
+
while_thread_is_running do
|
|
16
|
+
begin
|
|
17
|
+
@client.run
|
|
18
|
+
rescue => e
|
|
19
|
+
Thread.current[:exception] = e
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
report_exceptions
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def stop
|
|
28
|
+
@client.stop
|
|
29
|
+
@thread[:stop] = true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def thread_state
|
|
33
|
+
@thread.status
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def report_exceptions
|
|
39
|
+
exception = Thread.current[:exception]
|
|
40
|
+
return if exception.nil? || ignorable_exception?(exception)
|
|
41
|
+
|
|
42
|
+
if exception.respond_to? :cause # its a serious (Java?) exception
|
|
43
|
+
Thread.current[:stop] = true
|
|
44
|
+
callback :fatal_error_in_component, exception
|
|
45
|
+
else
|
|
46
|
+
Safely.report! exception
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def thread_is_stopping?
|
|
51
|
+
Thread.current[:stop]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def wait_time
|
|
55
|
+
@wait_time ||= 0.2
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def while_thread_is_running
|
|
59
|
+
until thread_is_stopping? do
|
|
60
|
+
yield
|
|
61
|
+
|
|
62
|
+
sleep wait_time
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -11,7 +11,11 @@ module Euston
|
|
|
11
11
|
private
|
|
12
12
|
|
|
13
13
|
def setup_amqp config
|
|
14
|
-
|
|
14
|
+
class << self.class
|
|
15
|
+
attr_accessor :amqp_connection
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
self.class.amqp_connection = HotBunnies.connect config
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
def setup_euston event_store_database_name
|
|
@@ -29,14 +33,15 @@ module Euston
|
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
def setup_mongo config
|
|
32
|
-
|
|
36
|
+
# logger arg will not work until jmongo forwards it correctly
|
|
37
|
+
connection = Mongo::Connection.from_uri config[:uri], :logger => @logger
|
|
33
38
|
|
|
34
39
|
class << self.class
|
|
35
|
-
attr_accessor :event_store_mongodb, :
|
|
40
|
+
attr_accessor :event_store_mongodb, :projections_mongodb
|
|
36
41
|
end
|
|
37
42
|
|
|
38
|
-
self.class.event_store_mongodb
|
|
39
|
-
self.class.
|
|
43
|
+
self.class.event_store_mongodb = Mongo::DB.new config[:event_store_database], connection
|
|
44
|
+
self.class.projections_mongodb = Mongo::DB.new config[:projections_database], connection
|
|
40
45
|
end
|
|
41
46
|
|
|
42
47
|
def setup_safely hoptoad_key
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
class Stopwatch
|
|
3
|
+
include Hollywood
|
|
4
|
+
|
|
5
|
+
def time decimal_places = 3, &block
|
|
6
|
+
start = Time.now.to_f
|
|
7
|
+
result = yield block
|
|
8
|
+
finish = Time.now.to_f
|
|
9
|
+
elapsed = finish - start
|
|
10
|
+
elapsed = elapsed.round(decimal_places) unless decimal_places.nil?
|
|
11
|
+
callback :finished, elapsed
|
|
12
|
+
result
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'i18n'
|
|
2
|
+
require 'hot_bunnies'
|
|
3
|
+
require 'macaddr'
|
|
4
|
+
require 'euston-rabbitmq'
|
|
5
|
+
|
|
6
|
+
require 'euston-daemons/pipeline/lib/command_processor/failed_message'
|
|
7
|
+
require 'euston-daemons/pipeline/lib/command_processor/default_handlers/retry_failed_message'
|
|
8
|
+
require 'euston-daemons/pipeline/lib/command_processor/component'
|
|
9
|
+
require 'euston-daemons/pipeline/lib/command_logger/log'
|
|
10
|
+
require 'euston-daemons/pipeline/lib/command_logger/component'
|
|
11
|
+
require 'euston-daemons/pipeline/lib/event_processor/default_handlers/message_failure'
|
|
12
|
+
require 'euston-daemons/pipeline/lib/event_processor/component'
|
|
13
|
+
require 'euston-daemons/pipeline/lib/event_store_dispatcher/component'
|
|
14
|
+
require 'euston-daemons/pipeline/lib/message_buffer/buffer'
|
|
15
|
+
require 'euston-daemons/pipeline/lib/message_buffer/component'
|
|
16
|
+
require 'euston-daemons/pipeline/lib/snapshotter/component'
|
|
17
|
+
require 'euston-daemons/pipeline/lib/daemon'
|
|
18
|
+
|
|
19
|
+
module Euston
|
|
20
|
+
module Daemons
|
|
21
|
+
module Pipeline
|
|
22
|
+
class DaemonEnvironment < Euston::DaemonEnvironment
|
|
23
|
+
class << self
|
|
24
|
+
attr_accessor :command_processors,
|
|
25
|
+
:command_handler_namespaces,
|
|
26
|
+
:command_loggers,
|
|
27
|
+
:event_handler_namespaces,
|
|
28
|
+
:event_processors,
|
|
29
|
+
:event_store_dispatchers,
|
|
30
|
+
:event_store_dispatcher_wait_time,
|
|
31
|
+
:message_buffers,
|
|
32
|
+
:message_buffer_wait_time,
|
|
33
|
+
:snapshotters,
|
|
34
|
+
:snapshotter_wait_time,
|
|
35
|
+
:snapshot_threshold
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def initialize data
|
|
39
|
+
@logger = data[:logger]
|
|
40
|
+
@daemon_config = data[:daemon_config]
|
|
41
|
+
@i18n_locales_path = @daemon_config[:i18n_locales_path]
|
|
42
|
+
|
|
43
|
+
@amqp_config = ErbYaml.read data[:amqp_config_path], data[:environment]
|
|
44
|
+
@mongo_config = ErbYaml.read data[:mongo_config_path], data[:environment]
|
|
45
|
+
|
|
46
|
+
self.class.command_handler_namespaces = data[:command_handler_namespaces]
|
|
47
|
+
self.class.event_handler_namespaces = data[:event_handler_namespaces]
|
|
48
|
+
|
|
49
|
+
self.class.command_processors = @daemon_config[:command_processors].to_i
|
|
50
|
+
self.class.command_loggers = @daemon_config[:command_loggers].to_i
|
|
51
|
+
self.class.event_processors = @daemon_config[:event_processors].to_i
|
|
52
|
+
self.class.event_store_dispatchers = @daemon_config[:event_store_dispatchers].to_i
|
|
53
|
+
self.class.event_store_dispatcher_wait_time = @daemon_config[:event_store_dispatcher_wait_time].to_f
|
|
54
|
+
self.class.message_buffers = @daemon_config[:message_buffers].to_i
|
|
55
|
+
self.class.message_buffer_wait_time = @daemon_config[:message_buffer_wait_time].to_f
|
|
56
|
+
self.class.snapshotters = @daemon_config[:snapshotters].to_i
|
|
57
|
+
self.class.snapshotter_wait_time = @daemon_config[:snapshotter_wait_time].to_f
|
|
58
|
+
self.class.snapshot_threshold = @daemon_config[:snapshot_threshold].to_i
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def setup
|
|
62
|
+
setup_safely @daemon_config[:hoptoad_key]
|
|
63
|
+
setup_amqp @amqp_config
|
|
64
|
+
setup_mongo @mongo_config
|
|
65
|
+
setup_euston @mongo_config[:event_store_database]
|
|
66
|
+
|
|
67
|
+
I18n.load_path += Dir[@i18n_locales_path] unless @i18n_locales_path.nil?
|
|
68
|
+
|
|
69
|
+
self.class
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module Daemons
|
|
3
|
+
module Pipeline
|
|
4
|
+
module CommandLogger
|
|
5
|
+
class Component < Euston::DaemonComponent
|
|
6
|
+
extend RabbitMq::Exchanges
|
|
7
|
+
extend RabbitMq::Queues
|
|
8
|
+
|
|
9
|
+
def initialize channel, id = 1, logger = Euston::NullLogger.instance
|
|
10
|
+
@id = id
|
|
11
|
+
@log = logger
|
|
12
|
+
@channel = channel
|
|
13
|
+
@channel.prefetch = 1
|
|
14
|
+
@command_log = Log.new DaemonEnvironment.event_store_mongodb
|
|
15
|
+
@exchange = self.class.get_exchange channel, :commands
|
|
16
|
+
@queue = self.class.get_queue channel, @command_log.name
|
|
17
|
+
@queue.bind @exchange, :routing_key => "#{@exchange.name}.#"
|
|
18
|
+
|
|
19
|
+
@queue.when(:message_decode_failed => method(:log_failure),
|
|
20
|
+
:message_failed => method(:message_failed),
|
|
21
|
+
:message_received => method(:write_message_to_log))
|
|
22
|
+
|
|
23
|
+
@consumer = @queue.consumer
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def log_failure message, error
|
|
29
|
+
return if ignorable_exception? error
|
|
30
|
+
|
|
31
|
+
text = "Command logger #{@id} failed.\n [Error] #{error.message}\n [Payload] #{message}"
|
|
32
|
+
err = Euston::RabbitMq::MessageDecodeFailedError.new text
|
|
33
|
+
err.set_backtrace error.backtrace
|
|
34
|
+
|
|
35
|
+
Safely.report! err
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def message_failed message, error, reactive_message
|
|
39
|
+
log_failure message, error
|
|
40
|
+
reactive_message.ack
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def next_iteration
|
|
44
|
+
@queue.safe_subscribe_with_timeout @consumer
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def write_message_to_log message
|
|
48
|
+
@command_log.write_command message
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module Daemons
|
|
3
|
+
module Pipeline
|
|
4
|
+
module CommandLogger
|
|
5
|
+
class Log
|
|
6
|
+
def initialize mongodb
|
|
7
|
+
@name = 'command_log'
|
|
8
|
+
mongodb.create_collection @name unless mongodb.collection_names.include? @name
|
|
9
|
+
|
|
10
|
+
@collection = mongodb.collection @name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
attr_reader :name
|
|
14
|
+
|
|
15
|
+
def write_command command
|
|
16
|
+
timestamp = Time.now.to_f
|
|
17
|
+
|
|
18
|
+
doc = { '_id' => command[:headers][:id],
|
|
19
|
+
'type' => command[:headers][:type],
|
|
20
|
+
'version' => command[:headers][:version],
|
|
21
|
+
'timestamp' => timestamp,
|
|
22
|
+
'timestamp_for_humans' => Time.at(timestamp),
|
|
23
|
+
'json' => ActiveSupport::JSON.encode(command) }
|
|
24
|
+
|
|
25
|
+
@collection.insert doc
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module Daemons
|
|
3
|
+
module Pipeline
|
|
4
|
+
module CommandProcessor
|
|
5
|
+
class Component < Euston::DaemonComponent
|
|
6
|
+
include Euston::CommandHandlerPrivateMethodNames
|
|
7
|
+
|
|
8
|
+
def initialize channel, handlers, id = 1, logger = Euston::NullLogger.instance
|
|
9
|
+
@channel = channel
|
|
10
|
+
@channel.prefetch = 1
|
|
11
|
+
@handlers = handlers
|
|
12
|
+
@id = id
|
|
13
|
+
@log = logger
|
|
14
|
+
@process_method = method(:process_message)
|
|
15
|
+
@stopwatch = Stopwatch.new.when(:finished => method(:log_elapsed_time))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def next_iteration
|
|
21
|
+
Euston::RabbitMq::RetryingSubscription.new(@channel, :command_handlers, @log)
|
|
22
|
+
.when(:message_received => @process_method)
|
|
23
|
+
.subscribe
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def process_message message
|
|
27
|
+
@stopwatch.time do
|
|
28
|
+
command_headers = CommandHeaders.from_hash(message[:headers]).freeze
|
|
29
|
+
command_body = message[:body].freeze
|
|
30
|
+
|
|
31
|
+
handler_type = command_headers.type.to_s.camelize.to_sym
|
|
32
|
+
reference = @handlers.find { |reference| reference.name == handler_type }
|
|
33
|
+
|
|
34
|
+
if reference.nil?
|
|
35
|
+
Euston::CommandBus.publish command_headers, command_body, @log
|
|
36
|
+
else
|
|
37
|
+
handler_method_name = self.class.command_handler_method_name command_headers.version
|
|
38
|
+
reference.handler.new.send handler_method_name, command_headers, command_body
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def log_elapsed_time elapsed_time
|
|
44
|
+
@log.debug "Command handler client #{@id} processed a message in #{elapsed_time} sec(s)"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
data/lib/euston-daemons/pipeline/lib/command_processor/default_handlers/retry_failed_message.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module Daemons
|
|
3
|
+
module Pipeline
|
|
4
|
+
module CommandProcessor
|
|
5
|
+
module DefaultHandlers
|
|
6
|
+
class RetryFailedMessage
|
|
7
|
+
include Euston::CommandHandler
|
|
8
|
+
|
|
9
|
+
version 1 do |headers, command|
|
|
10
|
+
failed_messages = FailedMessage.new DaemonEnvironment.event_store_mongodb
|
|
11
|
+
message = failed_messages.get_by_id command[:id]
|
|
12
|
+
|
|
13
|
+
unless message.nil?
|
|
14
|
+
routing_key = message['routing_key']
|
|
15
|
+
exchange = routing_key.split('.').first
|
|
16
|
+
|
|
17
|
+
headers = message['headers'].merge(:id => command[:id],
|
|
18
|
+
:type => message['type'],
|
|
19
|
+
:version => message['version'] )
|
|
20
|
+
|
|
21
|
+
retry_message = { :headers => headers, :body => message['body'] }
|
|
22
|
+
|
|
23
|
+
buffer = MessageBuffer::Buffer.new DaemonEnvironment.event_store_mongodb
|
|
24
|
+
buffer.enqueue exchange, retry_message
|
|
25
|
+
|
|
26
|
+
failed_messages.remove_by_id command[:id]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module Daemons
|
|
3
|
+
module Pipeline
|
|
4
|
+
module CommandProcessor
|
|
5
|
+
class FailedMessage
|
|
6
|
+
def initialize mongodb
|
|
7
|
+
name = 'failed_messages'
|
|
8
|
+
mongodb.create_collection name unless mongodb.collection_names.include? name
|
|
9
|
+
|
|
10
|
+
@collection = mongodb.collection name
|
|
11
|
+
@collection.ensure_index [ ['failure_timestamp', Mongo::ASCENDING] ], :unique => false, :name => 'failed_messages_failure_timestamp_index'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get_by_id id
|
|
15
|
+
@collection.find_one({ '_id' => id })
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def find_all
|
|
19
|
+
@collection.find({}, { :sort => [ 'failure_timestamp', Mongo::DESCENDING ] })
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def log_failure failure
|
|
23
|
+
failure.recursive_stringify_keys!
|
|
24
|
+
failure['_id'] = failure.delete 'message_id'
|
|
25
|
+
|
|
26
|
+
@collection.save(failure, :safe => { :fsync => true })
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def remove_by_id id
|
|
30
|
+
@collection.remove({ '_id' => id }, :safe => { :fsync => true })
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|