euston-daemons 1.0.4-java → 1.1.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 +3 -1
- data/Rakefile +2 -3
- data/euston-daemons.gemspec +61 -26
- data/lib/euston-daemons/command_processor_daemon/config/environment.rb +27 -18
- data/lib/euston-daemons/command_processor_daemon/lib/clients/command_handler.rb +37 -0
- data/lib/euston-daemons/command_processor_daemon/lib/command_handlers/retry_failed_message.rb +35 -0
- data/lib/euston-daemons/command_processor_daemon/lib/daemon.rb +11 -32
- data/lib/euston-daemons/command_processor_daemon/lib/mongo_models/failed_message.rb +34 -0
- data/lib/euston-daemons/command_processor_daemon/rake_task.rb +15 -13
- data/lib/euston-daemons/euston/daemon.rb +93 -0
- data/lib/euston-daemons/euston/daemon_client.rb +24 -0
- data/lib/euston-daemons/euston/daemon_component.rb +65 -0
- data/lib/euston-daemons/euston/daemon_environment.rb +54 -0
- data/lib/euston-daemons/event_processor_daemon/config/environment.rb +27 -16
- data/lib/euston-daemons/event_processor_daemon/lib/clients/event_handler.rb +42 -0
- data/lib/euston-daemons/event_processor_daemon/lib/daemon.rb +13 -60
- data/lib/euston-daemons/event_processor_daemon/lib/event_handlers/message_failure.rb +27 -0
- data/lib/euston-daemons/event_processor_daemon/rake_task.rb +18 -16
- data/lib/euston-daemons/message_buffer_daemon/config/environment.rb +39 -25
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_cleanup.rb +9 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_publisher.rb +9 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_logger.rb +9 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/euston_exchange_accessors.rb +15 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_cleanup.rb +9 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_publisher.rb +9 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_logger.rb +9 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_store_dispatcher.rb +25 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_cleanup.rb +52 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_publisher.rb +37 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_logger.rb +45 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/clients/mongo_model_accessors.rb +21 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/daemon.rb +11 -42
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_buffer.rb +11 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_log.rb +11 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_buffer.rb +11 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_log.rb +11 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_buffer.rb +57 -0
- data/lib/euston-daemons/message_buffer_daemon/lib/{read_model → mongo_models}/message_log.rb +4 -11
- data/lib/euston-daemons/message_buffer_daemon/rake_task.rb +13 -11
- data/lib/euston-daemons/rake_task.rb +41 -65
- data/lib/euston-daemons/rake_tasks.rb +5 -5
- data/lib/euston-daemons/snapshot_daemon/lib/clients/snapshotter.rb +43 -0
- data/lib/euston-daemons/version.rb +1 -1
- data/lib/euston-daemons.rb +6 -1
- data/sample/Rakefile +63 -0
- data/sample/amqp_config.yml +14 -0
- data/sample/command_handlers.rb +17 -0
- data/sample/command_processor_daemon_config.yml +9 -0
- data/sample/event_handlers.rb +21 -0
- data/sample/event_processor_daemon_config.yml +8 -0
- data/sample/message_buffer_daemon_config.yml +8 -0
- data/sample/mongoid_config.yml +13 -0
- data/sample/pids/.placeholder +0 -0
- data/spec/daemons/command_buffer_publisher_spec.rb +110 -0
- data/spec/daemons/command_handler_spec.rb +48 -0
- data/spec/daemons/event_handler_spec.rb +55 -0
- data/spec/daemons/snapshot_client_spec.rb +98 -0
- data/spec/spec_helper.rb +77 -0
- data/spec/support/factories/commands.rb +16 -0
- data/spec/support/factories/commit.rb +7 -0
- data/spec/support/factories/event_message.rb +12 -0
- data/spec/support/factories/events.rb +8 -0
- data/spec/support/filters.rb +14 -0
- data/spec/support/sample_model/commands.rb +14 -0
- data/spec/support/sample_model/counter.rb +36 -0
- data/spec/support/sample_model/counter2.rb +46 -0
- data/spec/support/stub_retrying_subscription.rb +9 -0
- metadata +134 -67
- data/lib/euston-daemons/command_processor_daemon/lib/components/command_handler_component.rb +0 -56
- data/lib/euston-daemons/command_processor_daemon/lib/settings.rb +0 -22
- data/lib/euston-daemons/event_processor_daemon/lib/components/event_handler_component.rb +0 -58
- data/lib/euston-daemons/event_processor_daemon/lib/settings.rb +0 -26
- data/lib/euston-daemons/framework/basic_component.rb +0 -33
- data/lib/euston-daemons/framework/channel_thread.rb +0 -22
- data/lib/euston-daemons/framework/component_shutdown.rb +0 -22
- data/lib/euston-daemons/framework/daemon.rb +0 -27
- data/lib/euston-daemons/framework/handler_bindings_component.rb +0 -56
- data/lib/euston-daemons/framework/queue.rb +0 -71
- data/lib/euston-daemons/message_buffer_daemon/lib/components/buffer_component.rb +0 -73
- data/lib/euston-daemons/message_buffer_daemon/lib/components/event_store_component.rb +0 -52
- data/lib/euston-daemons/message_buffer_daemon/lib/message_logger.rb +0 -54
- data/lib/euston-daemons/message_buffer_daemon/lib/publisher.rb +0 -56
- data/lib/euston-daemons/message_buffer_daemon/lib/settings.rb +0 -14
- data/lib/euston-daemons/message_buffer_daemon/lib/subscriber.rb +0 -60
data/Gemfile
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
source :rubygems
|
|
2
2
|
gemspec
|
|
3
3
|
|
|
4
|
-
gem '
|
|
4
|
+
gem 'cranky', :git => 'https://github.com/leemhenson/cranky.git', :branch => 'hashes'
|
|
5
|
+
gem 'ffaker', :git => 'https://github.com/leemhenson/ffaker.git', :branch => 'countries'
|
|
6
|
+
gem 'safely', :git => 'https://github.com/leemhenson/safely.git', :branch => 'override_strategies'
|
data/Rakefile
CHANGED
|
@@ -71,11 +71,10 @@ end
|
|
|
71
71
|
#
|
|
72
72
|
#############################################################################
|
|
73
73
|
|
|
74
|
-
default_rspec_opts = %w[--colour --format Fuubar]
|
|
75
|
-
|
|
76
74
|
desc "Run all examples"
|
|
77
75
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
|
78
|
-
t.rspec_opts =
|
|
76
|
+
t.rspec_opts = ['-r ./spec/spec_helper.rb', '--colour', '--format Fuubar']
|
|
77
|
+
t.pattern = 'spec/**/*_spec.rb'
|
|
79
78
|
end
|
|
80
79
|
|
|
81
80
|
#############################################################################
|
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.0
|
|
3
|
+
s.version = '1.1.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']
|
|
@@ -16,34 +16,68 @@ Gem::Specification.new do |s|
|
|
|
16
16
|
euston-daemons.gemspec
|
|
17
17
|
lib/euston-daemons.rb
|
|
18
18
|
lib/euston-daemons/command_processor_daemon/config/environment.rb
|
|
19
|
-
lib/euston-daemons/command_processor_daemon/lib/
|
|
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
|
|
20
21
|
lib/euston-daemons/command_processor_daemon/lib/daemon.rb
|
|
21
|
-
lib/euston-daemons/command_processor_daemon/lib/
|
|
22
|
+
lib/euston-daemons/command_processor_daemon/lib/mongo_models/failed_message.rb
|
|
22
23
|
lib/euston-daemons/command_processor_daemon/rake_task.rb
|
|
24
|
+
lib/euston-daemons/euston/daemon.rb
|
|
25
|
+
lib/euston-daemons/euston/daemon_client.rb
|
|
26
|
+
lib/euston-daemons/euston/daemon_component.rb
|
|
27
|
+
lib/euston-daemons/euston/daemon_environment.rb
|
|
23
28
|
lib/euston-daemons/event_processor_daemon/config/environment.rb
|
|
24
|
-
lib/euston-daemons/event_processor_daemon/lib/
|
|
29
|
+
lib/euston-daemons/event_processor_daemon/lib/clients/event_handler.rb
|
|
25
30
|
lib/euston-daemons/event_processor_daemon/lib/daemon.rb
|
|
26
|
-
lib/euston-daemons/event_processor_daemon/lib/
|
|
31
|
+
lib/euston-daemons/event_processor_daemon/lib/event_handlers/message_failure.rb
|
|
27
32
|
lib/euston-daemons/event_processor_daemon/rake_task.rb
|
|
28
|
-
lib/euston-daemons/framework/basic_component.rb
|
|
29
|
-
lib/euston-daemons/framework/channel_thread.rb
|
|
30
|
-
lib/euston-daemons/framework/component_shutdown.rb
|
|
31
|
-
lib/euston-daemons/framework/daemon.rb
|
|
32
|
-
lib/euston-daemons/framework/handler_bindings_component.rb
|
|
33
|
-
lib/euston-daemons/framework/queue.rb
|
|
34
33
|
lib/euston-daemons/message_buffer_daemon/config/environment.rb
|
|
35
|
-
lib/euston-daemons/message_buffer_daemon/lib/
|
|
36
|
-
lib/euston-daemons/message_buffer_daemon/lib/
|
|
34
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_cleanup.rb
|
|
35
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_publisher.rb
|
|
36
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/command_logger.rb
|
|
37
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/euston_exchange_accessors.rb
|
|
38
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_cleanup.rb
|
|
39
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_publisher.rb
|
|
40
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/event_logger.rb
|
|
41
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/event_store_dispatcher.rb
|
|
42
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_cleanup.rb
|
|
43
|
+
lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_publisher.rb
|
|
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
|
|
37
46
|
lib/euston-daemons/message_buffer_daemon/lib/daemon.rb
|
|
38
|
-
lib/euston-daemons/message_buffer_daemon/lib/
|
|
39
|
-
lib/euston-daemons/message_buffer_daemon/lib/
|
|
40
|
-
lib/euston-daemons/message_buffer_daemon/lib/
|
|
41
|
-
lib/euston-daemons/message_buffer_daemon/lib/
|
|
42
|
-
lib/euston-daemons/message_buffer_daemon/lib/
|
|
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
|
|
43
53
|
lib/euston-daemons/message_buffer_daemon/rake_task.rb
|
|
44
54
|
lib/euston-daemons/rake_task.rb
|
|
45
55
|
lib/euston-daemons/rake_tasks.rb
|
|
56
|
+
lib/euston-daemons/snapshot_daemon/lib/clients/snapshotter.rb
|
|
46
57
|
lib/euston-daemons/version.rb
|
|
58
|
+
sample/Rakefile
|
|
59
|
+
sample/amqp_config.yml
|
|
60
|
+
sample/command_handlers.rb
|
|
61
|
+
sample/command_processor_daemon_config.yml
|
|
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
|
|
71
|
+
spec/spec_helper.rb
|
|
72
|
+
spec/support/factories/commands.rb
|
|
73
|
+
spec/support/factories/commit.rb
|
|
74
|
+
spec/support/factories/event_message.rb
|
|
75
|
+
spec/support/factories/events.rb
|
|
76
|
+
spec/support/filters.rb
|
|
77
|
+
spec/support/sample_model/commands.rb
|
|
78
|
+
spec/support/sample_model/counter.rb
|
|
79
|
+
spec/support/sample_model/counter2.rb
|
|
80
|
+
spec/support/stub_retrying_subscription.rb
|
|
47
81
|
]
|
|
48
82
|
# = MANIFEST =
|
|
49
83
|
|
|
@@ -53,21 +87,22 @@ Gem::Specification.new do |s|
|
|
|
53
87
|
s.add_dependency 'activemodel', '~> 3.0.0'
|
|
54
88
|
s.add_dependency 'activesupport', '~> 3.0.0'
|
|
55
89
|
s.add_dependency 'erb-yaml', '~> 1.0.0'
|
|
90
|
+
s.add_dependency 'euston', '~> 1.1.0'
|
|
91
|
+
s.add_dependency 'euston-eventstore', '~> 1.1.0'
|
|
92
|
+
s.add_dependency 'euston-rabbitmq', '~> 1.1.0'
|
|
56
93
|
s.add_dependency 'hollywood', '~> 1.0.0'
|
|
57
94
|
s.add_dependency 'i18n', '~> 0.5.0'
|
|
58
|
-
s.add_dependency 'require_all', '~> 1.2.0'
|
|
59
95
|
s.add_dependency 'safely', '~> 0.3.0'
|
|
60
96
|
|
|
61
97
|
if RUBY_PLATFORM.to_s == 'java'
|
|
62
|
-
s.add_dependency 'euston-rabbitmq', '~> 1.0.0'
|
|
63
98
|
s.add_dependency 'jessica', '~> 1.0.0'
|
|
64
|
-
s.add_dependency 'jmongo', '~> 1.
|
|
99
|
+
s.add_dependency 'jmongo', '~> 1.1.0'
|
|
65
100
|
end
|
|
66
101
|
|
|
67
|
-
s.
|
|
68
|
-
s.
|
|
69
|
-
s.
|
|
70
|
-
|
|
71
|
-
|
|
102
|
+
s.add_development_dependency 'awesome_print', '~> 0.4.0'
|
|
103
|
+
s.add_development_dependency 'cranky', '~> 0.2.0'
|
|
104
|
+
s.add_development_dependency 'ffaker', '~> 1.8.0'
|
|
105
|
+
s.add_development_dependency 'fuubar', '~> 0.0.0'
|
|
106
|
+
s.add_development_dependency 'rabbitmqadmin-cli', '~> 1.0.2'
|
|
72
107
|
s.add_development_dependency 'rspec', '~> 2.6.0'
|
|
73
108
|
end
|
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
require 'jessica'
|
|
2
|
-
require 'euston'
|
|
3
|
-
require 'euston-eventstore'
|
|
4
2
|
require 'euston-rabbitmq'
|
|
5
|
-
require_rel '../lib'
|
|
6
3
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
require 'euston-daemons/command_processor_daemon/lib/mongo_models/failed_message'
|
|
5
|
+
require 'euston-daemons/command_processor_daemon/lib/command_handlers/retry_failed_message'
|
|
6
|
+
require 'euston-daemons/command_processor_daemon/lib/clients/command_handler'
|
|
7
|
+
require 'euston-daemons/command_processor_daemon/lib/daemon'
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
module Euston
|
|
10
|
+
module CommandProcessorDaemon
|
|
11
|
+
class DaemonEnvironment < Euston::DaemonEnvironment
|
|
12
|
+
class << self
|
|
13
|
+
attr_accessor :command_handler_namespaces, :client_instances
|
|
14
|
+
end
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
def initialize data
|
|
17
|
+
@logger = data[:logger]
|
|
18
|
+
@amqp_config = ErbYaml.read data[:amqp_config_path], data[:environment]
|
|
19
|
+
@daemon_config = ErbYaml.read data[:daemon_config_path], data[:environment]
|
|
20
|
+
@mongoid_config = ErbYaml.read data[:mongoid_config_path], data[:environment]
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
self.class.client_instances = @daemon_config[:client_instances]
|
|
23
|
+
self.class.command_handler_namespaces = data[:command_handler_namespaces]
|
|
24
|
+
end
|
|
18
25
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
def setup
|
|
27
|
+
setup_safely @daemon_config[:hoptoad_key]
|
|
28
|
+
setup_amqp @amqp_config
|
|
29
|
+
setup_mongo @mongoid_config
|
|
30
|
+
setup_euston @mongoid_config[:event_store_database]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module CommandProcessorDaemon
|
|
3
|
+
class CommandHandler < Euston::DaemonClient
|
|
4
|
+
def initialize channel, handlers, logger
|
|
5
|
+
@channel = channel
|
|
6
|
+
@channel.prefetch 1
|
|
7
|
+
@handlers = handlers
|
|
8
|
+
@log = logger
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def next_iteration
|
|
14
|
+
message_received = Proc.new do |message|
|
|
15
|
+
command_headers = CommandHeaders.from_hash(message[:headers]).freeze
|
|
16
|
+
command_body = message[:body].freeze
|
|
17
|
+
|
|
18
|
+
handler_type = command_headers.type.to_s.camelize.to_sym
|
|
19
|
+
handler_method_name = "__version__#{command_headers.version}"
|
|
20
|
+
reference = @handlers.find { |reference| reference.name == handler_type }
|
|
21
|
+
|
|
22
|
+
if reference.nil?
|
|
23
|
+
@log.debug "Delivering command #{command_headers} to command bus"
|
|
24
|
+
Euston::CommandBus.publish command_headers, command_body
|
|
25
|
+
else
|
|
26
|
+
@log.debug "Delivering command #{command_headers} to #{reference.name}.#{handler_method_name}"
|
|
27
|
+
reference.handler.new.send handler_method_name, command_headers, command_body
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
Euston::RabbitMq::RetryingSubscription.new(@channel, :command_handlers, @log)
|
|
32
|
+
.when(:message_received => message_received)
|
|
33
|
+
.subscribe
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module CommandProcessorDaemon
|
|
3
|
+
module CommandHandlers
|
|
4
|
+
class RetryFailedMessage
|
|
5
|
+
include Euston::CommandHandler
|
|
6
|
+
|
|
7
|
+
version 1 do |headers, command|
|
|
8
|
+
model = MongoModel::FailedMessage.new DaemonEnvironment.event_store_mongodb
|
|
9
|
+
message = model.get_by_id command[:id]
|
|
10
|
+
|
|
11
|
+
unless message.nil?
|
|
12
|
+
routing_key = message['routing_key']
|
|
13
|
+
exchange = routing_key.split('.').first
|
|
14
|
+
|
|
15
|
+
headers = message['headers'].merge(:id => command[:id],
|
|
16
|
+
:type => message['type'],
|
|
17
|
+
:version => message['version'] )
|
|
18
|
+
|
|
19
|
+
if exchange == 'commands'
|
|
20
|
+
buffer = MessageBufferDaemon::MongoModel::CommandBuffer
|
|
21
|
+
elsif exchange == 'events'
|
|
22
|
+
buffer = MessageBufferDaemon::MongoModel::EventBuffer
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
buffer = buffer.new DaemonEnvironment.event_store_mongodb
|
|
26
|
+
buffer.push :headers => headers,
|
|
27
|
+
:body => message['body']
|
|
28
|
+
|
|
29
|
+
model.remove_by_id command[:id]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -1,42 +1,21 @@
|
|
|
1
1
|
module Euston
|
|
2
2
|
module CommandProcessorDaemon
|
|
3
|
-
class Daemon
|
|
4
|
-
|
|
3
|
+
class Daemon < Euston::Daemon
|
|
4
|
+
private
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
def pre_registration_setup
|
|
7
|
+
handler_finder = Euston::RabbitMq::HandlerFinder.new [Euston::CommandHandler]
|
|
8
|
+
handler_finder.namespaces.push Euston::CommandProcessorDaemon::CommandHandlers, *DaemonEnvironment.command_handler_namespaces
|
|
9
|
+
@handlers = handler_finder.find
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# @ctx = ctx
|
|
11
|
-
@clients = {}
|
|
12
|
-
|
|
13
|
-
Settings.client_instances.times do |i|
|
|
14
|
-
@clients["command_component_#{i.succ}"] = CommandHandlerComponent.new self
|
|
15
|
-
end
|
|
11
|
+
binder = Euston::RabbitMq::CommandHandlerBinder.new @handlers
|
|
12
|
+
binder.ensure_bindings_exist
|
|
16
13
|
end
|
|
17
14
|
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
EUSTON_LOG.debug "Starting component: #{name}"
|
|
22
|
-
component.start
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
EUSTON_LOG.debug "Components started"
|
|
26
|
-
|
|
27
|
-
@clients.each do |name, component|
|
|
28
|
-
EUSTON_LOG.debug("Thread state of #{name}: #{component.thread_state}")
|
|
15
|
+
def register_components
|
|
16
|
+
(1..DaemonEnvironment.client_instances).each do |i|
|
|
17
|
+
register_component "command_handler_#{i}".to_sym, CommandHandler.new(AMQP::Channel.new, @handlers, @log)
|
|
29
18
|
end
|
|
30
|
-
|
|
31
|
-
@queue.pop #<-------- stops here until interrupted
|
|
32
|
-
|
|
33
|
-
@clients.each do |name, component|
|
|
34
|
-
EUSTON_LOG.debug "Stopping component: #{name}"
|
|
35
|
-
component.stop
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
report_shutdown_reasons
|
|
39
|
-
EUSTON_LOG.debug "Components stopped"
|
|
40
19
|
end
|
|
41
20
|
end
|
|
42
21
|
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
module CommandProcessorDaemon
|
|
3
|
+
module MongoModel
|
|
4
|
+
class FailedMessage
|
|
5
|
+
def initialize mongodb
|
|
6
|
+
name = 'failed_messages'
|
|
7
|
+
mongodb.create_collection name unless mongodb.collection_names.include? name
|
|
8
|
+
|
|
9
|
+
@collection = mongodb.collection name
|
|
10
|
+
@collection.ensure_index [ ['failure_timestamp', Mongo::ASCENDING] ], :unique => false, :name => 'failed_messages_failure_timestamp_index'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def get_by_id id
|
|
14
|
+
@collection.find_one({ '_id' => id })
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def find_all
|
|
18
|
+
@collection.find({}, { :sort => [ 'failure_timestamp', Mongo::DESCENDING ] })
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def log_failure failure
|
|
22
|
+
failure.recursive_stringify_keys!
|
|
23
|
+
failure['_id'] = failure.delete 'message_id'
|
|
24
|
+
|
|
25
|
+
@collection.save(failure, :safe => { :fsync => true })
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def remove_by_id id
|
|
29
|
+
@collection.remove({ '_id' => id }, :safe => { :fsync => true })
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -2,9 +2,9 @@ module Euston
|
|
|
2
2
|
class CommandProcessorRakeTask < Euston::Daemons::RakeTask
|
|
3
3
|
attr_accessor :amqp_config_path, :command_handler_namespaces, :daemon_config_path, :mongoid_config_path
|
|
4
4
|
|
|
5
|
-
def initialize
|
|
5
|
+
def initialize environment
|
|
6
6
|
@command_handler_namespaces = []
|
|
7
|
-
super
|
|
7
|
+
super environment, :command_processor_daemon
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def before_creating_task
|
|
@@ -12,23 +12,25 @@ module Euston
|
|
|
12
12
|
@daemon_class = 'Euston::CommandProcessorDaemon::Daemon'
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
def initialize_settings
|
|
16
|
+
@logger.debug "AMQP config path: #{@amqp_config_path}"
|
|
17
|
+
@data[:amqp_config_path] = @amqp_config_path
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
@logger.debug "Command handler namespaces: #{@command_handler_namespaces}"
|
|
20
|
+
@data[:command_handler_namespaces] = @command_handler_namespaces
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
@logger.debug "Daemon config path: #{@daemon_config_path}"
|
|
23
|
+
@data[:daemon_config_path] = @daemon_config_path
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
@logger.debug "Mongoid config path: #{@mongoid_config_path}"
|
|
26
|
+
@data[:mongoid_config_path] = @mongoid_config_path
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def load_environment
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
@logger.debug "Loading environment"
|
|
31
|
+
require 'euston-daemons/command_processor_daemon/config/environment'
|
|
32
|
+
|
|
33
|
+
Euston::CommandProcessorDaemon::DaemonEnvironment.new(@data).setup
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
class Daemon
|
|
3
|
+
def initialize data
|
|
4
|
+
@log = data[:logger]
|
|
5
|
+
@queue = Queue.new
|
|
6
|
+
@components = []
|
|
7
|
+
@errors = []
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def run
|
|
11
|
+
Thread.abort_on_exception = true
|
|
12
|
+
|
|
13
|
+
pre_registration_setup
|
|
14
|
+
register_components
|
|
15
|
+
trap_exit_signals
|
|
16
|
+
start_components
|
|
17
|
+
wait_for_shutdown_event
|
|
18
|
+
stop_components
|
|
19
|
+
report_shutdown_reasons
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def pre_registration_setup
|
|
25
|
+
# virtual
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def register_component name, klass
|
|
29
|
+
component = Euston::DaemonComponent.new @log, name, klass, self
|
|
30
|
+
component.when(:fatal_error_in_component => method(:shutdown))
|
|
31
|
+
|
|
32
|
+
@components << component
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def register_components
|
|
36
|
+
# virtual
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def report_shutdown_reasons
|
|
40
|
+
sleep 0.25
|
|
41
|
+
reports = []
|
|
42
|
+
|
|
43
|
+
until @errors.empty? do
|
|
44
|
+
e = @errors.shift
|
|
45
|
+
next if e.nil?
|
|
46
|
+
|
|
47
|
+
case e
|
|
48
|
+
when NativeException
|
|
49
|
+
Safely.report! e.cause
|
|
50
|
+
else
|
|
51
|
+
Safely.report! e
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def report_component_statuses
|
|
57
|
+
@components.each do |component|
|
|
58
|
+
@log.debug "Thread state of #{component.name}: #{component.thread_state}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def start_components
|
|
63
|
+
@components.each do |component|
|
|
64
|
+
@log.debug "Starting component: #{component.name}"
|
|
65
|
+
component.start
|
|
66
|
+
sleep 0.350
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def stop_components
|
|
71
|
+
@components.each do |component|
|
|
72
|
+
@log.debug "Stopping component: #{component.name}"
|
|
73
|
+
component.stop
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def shutdown error
|
|
78
|
+
@errors.push error unless error.nil?
|
|
79
|
+
@queue.push "SHUTDOWN"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def trap_exit_signals
|
|
83
|
+
signals = %W(INT TERM) & Signal.list.keys
|
|
84
|
+
signals.each { |sig| sig.freeze }.freeze
|
|
85
|
+
signals.each { |sig| Signal.trap(sig) { @queue.push(sig) } }
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def wait_for_shutdown_event
|
|
89
|
+
@log.debug "Awaiting shutdown event"
|
|
90
|
+
@queue.pop #<-------- stops here until interrupted
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
class DaemonClient
|
|
3
|
+
include Hollywood
|
|
4
|
+
|
|
5
|
+
def run
|
|
6
|
+
next_iteration unless stopped
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def stop
|
|
10
|
+
@stopped = true
|
|
11
|
+
@channel.disconnect unless @channel.nil? || !@channel.respond_to?(:disconnect)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def next_iteration
|
|
17
|
+
# abstract
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def stopped
|
|
21
|
+
@stopped ||= false
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
class DaemonComponent
|
|
3
|
+
include Hollywood
|
|
4
|
+
|
|
5
|
+
def initialize logger, name, client, owner
|
|
6
|
+
@log, @name, @client, @owner = logger, name, client, owner
|
|
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
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def stop
|
|
26
|
+
@client.stop
|
|
27
|
+
@thread[:stop] = true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def thread_state
|
|
31
|
+
@thread.status
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def report_exceptions
|
|
37
|
+
exception = Thread.current[:exception]
|
|
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]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def wait_time
|
|
54
|
+
@wait_time ||= 0.2
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def while_thread_is_running
|
|
58
|
+
until thread_is_stopping? do
|
|
59
|
+
yield
|
|
60
|
+
|
|
61
|
+
sleep wait_time
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Euston
|
|
2
|
+
class DaemonEnvironment
|
|
3
|
+
def initialize data
|
|
4
|
+
@logger = data[:logger]
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
# abstract
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def setup_amqp config
|
|
14
|
+
AMQP.settings.merge! config
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def setup_euston event_store_database_name
|
|
18
|
+
Euston::EventStore::Persistence::Mongodb::Config.instance.logger = @logger
|
|
19
|
+
Euston::EventStore::Persistence::Mongodb::Config.instance.database = event_store_database_name
|
|
20
|
+
|
|
21
|
+
class << self.class
|
|
22
|
+
attr_accessor :event_store
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
self.class.event_store = Euston::EventStore::Persistence::Mongodb::MongoPersistenceFactory.build
|
|
26
|
+
self.class.event_store.init
|
|
27
|
+
|
|
28
|
+
Euston::Repository.event_store = Euston::EventStore::OptimisticEventStore.new self.class.event_store
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def setup_mongo config
|
|
32
|
+
connection = Mongo::Connection.new config[:host], config[:port], :safe => config[:safe], :logger => @logger
|
|
33
|
+
|
|
34
|
+
class << self.class
|
|
35
|
+
attr_accessor :event_store_mongodb, :read_model_mongodb
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
self.class.event_store_mongodb = Mongo::DB.new config[:event_store_database], connection
|
|
39
|
+
self.class.read_model_mongodb = Mongo::DB.new config[:read_model_database], connection
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def setup_safely hoptoad_key
|
|
43
|
+
safely_strategies = [ Safely::Strategy::Log ]
|
|
44
|
+
|
|
45
|
+
unless hoptoad_key.nil?
|
|
46
|
+
Safely::Strategy::Hoptoad.hoptoad_key = data[:environment]
|
|
47
|
+
safely_strategies << Safely::Strategy::Hoptoad
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Safely::Strategy::Log.logger = @logger
|
|
51
|
+
Safely.configure { |config| config.strategies = safely_strategies }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|