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.
Files changed (84) hide show
  1. data/Gemfile +3 -1
  2. data/Rakefile +2 -3
  3. data/euston-daemons.gemspec +61 -26
  4. data/lib/euston-daemons/command_processor_daemon/config/environment.rb +27 -18
  5. data/lib/euston-daemons/command_processor_daemon/lib/clients/command_handler.rb +37 -0
  6. data/lib/euston-daemons/command_processor_daemon/lib/command_handlers/retry_failed_message.rb +35 -0
  7. data/lib/euston-daemons/command_processor_daemon/lib/daemon.rb +11 -32
  8. data/lib/euston-daemons/command_processor_daemon/lib/mongo_models/failed_message.rb +34 -0
  9. data/lib/euston-daemons/command_processor_daemon/rake_task.rb +15 -13
  10. data/lib/euston-daemons/euston/daemon.rb +93 -0
  11. data/lib/euston-daemons/euston/daemon_client.rb +24 -0
  12. data/lib/euston-daemons/euston/daemon_component.rb +65 -0
  13. data/lib/euston-daemons/euston/daemon_environment.rb +54 -0
  14. data/lib/euston-daemons/event_processor_daemon/config/environment.rb +27 -16
  15. data/lib/euston-daemons/event_processor_daemon/lib/clients/event_handler.rb +42 -0
  16. data/lib/euston-daemons/event_processor_daemon/lib/daemon.rb +13 -60
  17. data/lib/euston-daemons/event_processor_daemon/lib/event_handlers/message_failure.rb +27 -0
  18. data/lib/euston-daemons/event_processor_daemon/rake_task.rb +18 -16
  19. data/lib/euston-daemons/message_buffer_daemon/config/environment.rb +39 -25
  20. data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_cleanup.rb +9 -0
  21. data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_publisher.rb +9 -0
  22. data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_logger.rb +9 -0
  23. data/lib/euston-daemons/message_buffer_daemon/lib/clients/euston_exchange_accessors.rb +15 -0
  24. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_cleanup.rb +9 -0
  25. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_publisher.rb +9 -0
  26. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_logger.rb +9 -0
  27. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_store_dispatcher.rb +25 -0
  28. data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_cleanup.rb +52 -0
  29. data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_publisher.rb +37 -0
  30. data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_logger.rb +45 -0
  31. data/lib/euston-daemons/message_buffer_daemon/lib/clients/mongo_model_accessors.rb +21 -0
  32. data/lib/euston-daemons/message_buffer_daemon/lib/daemon.rb +11 -42
  33. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_buffer.rb +11 -0
  34. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_log.rb +11 -0
  35. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_buffer.rb +11 -0
  36. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_log.rb +11 -0
  37. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_buffer.rb +57 -0
  38. data/lib/euston-daemons/message_buffer_daemon/lib/{read_model → mongo_models}/message_log.rb +4 -11
  39. data/lib/euston-daemons/message_buffer_daemon/rake_task.rb +13 -11
  40. data/lib/euston-daemons/rake_task.rb +41 -65
  41. data/lib/euston-daemons/rake_tasks.rb +5 -5
  42. data/lib/euston-daemons/snapshot_daemon/lib/clients/snapshotter.rb +43 -0
  43. data/lib/euston-daemons/version.rb +1 -1
  44. data/lib/euston-daemons.rb +6 -1
  45. data/sample/Rakefile +63 -0
  46. data/sample/amqp_config.yml +14 -0
  47. data/sample/command_handlers.rb +17 -0
  48. data/sample/command_processor_daemon_config.yml +9 -0
  49. data/sample/event_handlers.rb +21 -0
  50. data/sample/event_processor_daemon_config.yml +8 -0
  51. data/sample/message_buffer_daemon_config.yml +8 -0
  52. data/sample/mongoid_config.yml +13 -0
  53. data/sample/pids/.placeholder +0 -0
  54. data/spec/daemons/command_buffer_publisher_spec.rb +110 -0
  55. data/spec/daemons/command_handler_spec.rb +48 -0
  56. data/spec/daemons/event_handler_spec.rb +55 -0
  57. data/spec/daemons/snapshot_client_spec.rb +98 -0
  58. data/spec/spec_helper.rb +77 -0
  59. data/spec/support/factories/commands.rb +16 -0
  60. data/spec/support/factories/commit.rb +7 -0
  61. data/spec/support/factories/event_message.rb +12 -0
  62. data/spec/support/factories/events.rb +8 -0
  63. data/spec/support/filters.rb +14 -0
  64. data/spec/support/sample_model/commands.rb +14 -0
  65. data/spec/support/sample_model/counter.rb +36 -0
  66. data/spec/support/sample_model/counter2.rb +46 -0
  67. data/spec/support/stub_retrying_subscription.rb +9 -0
  68. metadata +134 -67
  69. data/lib/euston-daemons/command_processor_daemon/lib/components/command_handler_component.rb +0 -56
  70. data/lib/euston-daemons/command_processor_daemon/lib/settings.rb +0 -22
  71. data/lib/euston-daemons/event_processor_daemon/lib/components/event_handler_component.rb +0 -58
  72. data/lib/euston-daemons/event_processor_daemon/lib/settings.rb +0 -26
  73. data/lib/euston-daemons/framework/basic_component.rb +0 -33
  74. data/lib/euston-daemons/framework/channel_thread.rb +0 -22
  75. data/lib/euston-daemons/framework/component_shutdown.rb +0 -22
  76. data/lib/euston-daemons/framework/daemon.rb +0 -27
  77. data/lib/euston-daemons/framework/handler_bindings_component.rb +0 -56
  78. data/lib/euston-daemons/framework/queue.rb +0 -71
  79. data/lib/euston-daemons/message_buffer_daemon/lib/components/buffer_component.rb +0 -73
  80. data/lib/euston-daemons/message_buffer_daemon/lib/components/event_store_component.rb +0 -52
  81. data/lib/euston-daemons/message_buffer_daemon/lib/message_logger.rb +0 -54
  82. data/lib/euston-daemons/message_buffer_daemon/lib/publisher.rb +0 -56
  83. data/lib/euston-daemons/message_buffer_daemon/lib/settings.rb +0 -14
  84. 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 'mongoid', :git => 'https://github.com/guyboertje/mongoid.git'
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 = default_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
  #############################################################################
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'euston-daemons'
3
- s.version = '1.0.4'
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/components/command_handler_component.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
20
21
  lib/euston-daemons/command_processor_daemon/lib/daemon.rb
21
- lib/euston-daemons/command_processor_daemon/lib/settings.rb
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/components/event_handler_component.rb
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/settings.rb
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/components/buffer_component.rb
36
- lib/euston-daemons/message_buffer_daemon/lib/components/event_store_component.rb
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/message_logger.rb
39
- lib/euston-daemons/message_buffer_daemon/lib/publisher.rb
40
- lib/euston-daemons/message_buffer_daemon/lib/read_model/message_log.rb
41
- lib/euston-daemons/message_buffer_daemon/lib/settings.rb
42
- lib/euston-daemons/message_buffer_daemon/lib/subscriber.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
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.0.0'
99
+ s.add_dependency 'jmongo', '~> 1.1.0'
65
100
  end
66
101
 
67
- s.add_dependency 'euston', '~> 1.0.0'
68
- s.add_dependency 'euston-eventstore', '~> 1.0.0'
69
- s.add_dependency 'mongoid-glue', '~> 1.0.0'
70
- # s.add_dependency 'mongoid'
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
- Safely::Strategy::Log.logger = EUSTON_LOG
8
- AMQP.settings.merge! ErbYaml.read(AMQP_CONFIG_PATH, EUSTON_ENV)
9
- Euston::CommandProcessorDaemon::Settings.configure ErbYaml.read(DAEMON_CONFIG_PATH, EUSTON_ENV)
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
- hash = ErbYaml.read(MONGOID_CONFIG_PATH, EUSTON_ENV)
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
- event_connection = Mongo::Connection.new hash[:host], hash[:port], :safe => hash[:safe] #, :logger => EUSTON_LOG
14
- read_connection = Mongo::Connection.new hash[:host], hash[:port], :safe => hash[:safe] #, :logger => EUSTON_LOG
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
- Euston::RabbitMq.event_store_mongodb = Mongo::DB.new(hash[:event_store_database], event_connection)
17
- Euston::RabbitMq.read_model_mongodb = Mongo::DB.new(hash[:read_model_database], read_connection)
22
+ self.class.client_instances = @daemon_config[:client_instances]
23
+ self.class.command_handler_namespaces = data[:command_handler_namespaces]
24
+ end
18
25
 
19
- Euston::EventStore::Persistence::Mongodb::Config.instance.logger = EUSTON_LOG
20
- Euston::EventStore::Persistence::Mongodb::Config.instance.database = Euston::CommandProcessorDaemon::Settings.mongo_db_name
21
-
22
- Euston::RabbitMq.event_store = Euston::EventStore::Persistence::Mongodb::MongoPersistenceFactory.build
23
- Euston::RabbitMq.event_store.init
24
-
25
- Euston::Repository.event_store = Euston::EventStore::OptimisticEventStore.new Euston::RabbitMq.event_store
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
- include Euston::Daemon
3
+ class Daemon < Euston::Daemon
4
+ private
5
5
 
6
- attr_reader :clients, :queue #,:ctx
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
- def initialize #(ctx)
9
- @queue = Queue.new
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 run
19
- @clients.each do |name, component|
20
- sleep 0.25
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(:command_processor_daemon)
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 initialize_paths
16
- EUSTON_LOG.debug "AMQP config path: #{@amqp_config_path}"
17
- Object.const_set :AMQP_CONFIG_PATH, @amqp_config_path
15
+ def initialize_settings
16
+ @logger.debug "AMQP config path: #{@amqp_config_path}"
17
+ @data[:amqp_config_path] = @amqp_config_path
18
18
 
19
- EUSTON_LOG.debug "Command handler namespaces: #{@command_handler_namespaces}"
20
- Object.const_set :COMMAND_HANDLER_NAMESPACES, @command_handler_namespaces
19
+ @logger.debug "Command handler namespaces: #{@command_handler_namespaces}"
20
+ @data[:command_handler_namespaces] = @command_handler_namespaces
21
21
 
22
- EUSTON_LOG.debug "Daemon config path: #{@daemon_config_path}"
23
- Object.const_set :DAEMON_CONFIG_PATH, @daemon_config_path
22
+ @logger.debug "Daemon config path: #{@daemon_config_path}"
23
+ @data[:daemon_config_path] = @daemon_config_path
24
24
 
25
- EUSTON_LOG.debug "Mongoid config path: #{@mongoid_config_path}"
26
- Object.const_set :MONGOID_CONFIG_PATH, @mongoid_config_path
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
- EUSTON_LOG.debug "Loading environment"
31
- require_rel 'config/environment.rb'
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