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.
Files changed (76) hide show
  1. data/Gemfile +1 -0
  2. data/euston-daemons.gemspec +27 -52
  3. data/lib/euston-daemons/euston/daemon.rb +7 -1
  4. data/lib/euston-daemons/euston/daemon_component.rb +9 -49
  5. data/lib/euston-daemons/euston/daemon_component_host.rb +66 -0
  6. data/lib/euston-daemons/euston/daemon_environment.rb +10 -5
  7. data/lib/euston-daemons/euston/exceptions.rb +9 -0
  8. data/lib/euston-daemons/euston/stopwatch.rb +15 -0
  9. data/lib/euston-daemons/pipeline/config/environment.rb +74 -0
  10. data/lib/euston-daemons/pipeline/lib/command_logger/component.rb +54 -0
  11. data/lib/euston-daemons/pipeline/lib/command_logger/log.rb +31 -0
  12. data/lib/euston-daemons/pipeline/lib/command_processor/component.rb +50 -0
  13. data/lib/euston-daemons/pipeline/lib/command_processor/default_handlers/retry_failed_message.rb +34 -0
  14. data/lib/euston-daemons/pipeline/lib/command_processor/failed_message.rb +36 -0
  15. data/lib/euston-daemons/pipeline/lib/daemon.rb +77 -0
  16. data/lib/euston-daemons/pipeline/lib/event_processor/component.rb +67 -0
  17. data/lib/euston-daemons/pipeline/lib/event_processor/default_handlers/message_failure.rb +30 -0
  18. data/lib/euston-daemons/pipeline/lib/event_store_dispatcher/component.rb +68 -0
  19. data/lib/euston-daemons/pipeline/lib/message_buffer/buffer.rb +85 -0
  20. data/lib/euston-daemons/pipeline/lib/message_buffer/component.rb +59 -0
  21. data/lib/euston-daemons/pipeline/lib/snapshotter/component.rb +48 -0
  22. data/lib/euston-daemons/pipeline/rake_task.rb +45 -0
  23. data/lib/euston-daemons/rake_task.rb +40 -19
  24. data/lib/euston-daemons/rake_tasks.rb +1 -3
  25. data/lib/euston-daemons/version.rb +1 -1
  26. data/lib/euston-daemons.rb +3 -1
  27. data/spec/daemons/{command_handler_spec.rb → command_processor_spec.rb} +3 -3
  28. data/spec/daemons/{event_handler_spec.rb → event_processor_spec.rb} +2 -2
  29. data/spec/daemons/{command_buffer_publisher_spec.rb → message_buffer_spec.rb} +19 -23
  30. data/spec/daemons/{snapshot_client_spec.rb → snapshotter_spec.rb} +3 -5
  31. data/spec/spec_helper.rb +23 -9
  32. data/spec/support/filters.rb +4 -5
  33. metadata +73 -88
  34. data/lib/euston-daemons/command_processor_daemon/config/environment.rb +0 -34
  35. data/lib/euston-daemons/command_processor_daemon/lib/clients/command_handler.rb +0 -37
  36. data/lib/euston-daemons/command_processor_daemon/lib/command_handlers/retry_failed_message.rb +0 -35
  37. data/lib/euston-daemons/command_processor_daemon/lib/daemon.rb +0 -22
  38. data/lib/euston-daemons/command_processor_daemon/lib/mongo_models/failed_message.rb +0 -34
  39. data/lib/euston-daemons/command_processor_daemon/rake_task.rb +0 -36
  40. data/lib/euston-daemons/euston/daemon_client.rb +0 -24
  41. data/lib/euston-daemons/event_processor_daemon/config/environment.rb +0 -36
  42. data/lib/euston-daemons/event_processor_daemon/lib/clients/event_handler.rb +0 -42
  43. data/lib/euston-daemons/event_processor_daemon/lib/daemon.rb +0 -24
  44. data/lib/euston-daemons/event_processor_daemon/lib/event_handlers/message_failure.rb +0 -27
  45. data/lib/euston-daemons/event_processor_daemon/rake_task.rb +0 -39
  46. data/lib/euston-daemons/message_buffer_daemon/config/environment.rb +0 -42
  47. data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_cleanup.rb +0 -9
  48. data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_buffer_publisher.rb +0 -9
  49. data/lib/euston-daemons/message_buffer_daemon/lib/clients/command_logger.rb +0 -9
  50. data/lib/euston-daemons/message_buffer_daemon/lib/clients/euston_exchange_accessors.rb +0 -15
  51. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_cleanup.rb +0 -9
  52. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_buffer_publisher.rb +0 -9
  53. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_logger.rb +0 -9
  54. data/lib/euston-daemons/message_buffer_daemon/lib/clients/event_store_dispatcher.rb +0 -25
  55. data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_cleanup.rb +0 -52
  56. data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_buffer_publisher.rb +0 -37
  57. data/lib/euston-daemons/message_buffer_daemon/lib/clients/message_logger.rb +0 -45
  58. data/lib/euston-daemons/message_buffer_daemon/lib/clients/mongo_model_accessors.rb +0 -21
  59. data/lib/euston-daemons/message_buffer_daemon/lib/daemon.rb +0 -17
  60. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_buffer.rb +0 -11
  61. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/command_log.rb +0 -11
  62. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_buffer.rb +0 -11
  63. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/event_log.rb +0 -11
  64. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_buffer.rb +0 -57
  65. data/lib/euston-daemons/message_buffer_daemon/lib/mongo_models/message_log.rb +0 -29
  66. data/lib/euston-daemons/message_buffer_daemon/rake_task.rb +0 -32
  67. data/lib/euston-daemons/snapshot_daemon/lib/clients/snapshotter.rb +0 -43
  68. data/sample/Rakefile +0 -63
  69. data/sample/amqp_config.yml +0 -14
  70. data/sample/command_handlers.rb +0 -17
  71. data/sample/command_processor_daemon_config.yml +0 -9
  72. data/sample/event_handlers.rb +0 -21
  73. data/sample/event_processor_daemon_config.yml +0 -8
  74. data/sample/message_buffer_daemon_config.yml +0 -8
  75. data/sample/mongoid_config.yml +0 -13
  76. 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'
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'euston-daemons'
3
- s.version = '1.1.0'
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/event_processor_daemon/config/environment.rb
29
- lib/euston-daemons/event_processor_daemon/lib/clients/event_handler.rb
30
- lib/euston-daemons/event_processor_daemon/lib/daemon.rb
31
- lib/euston-daemons/event_processor_daemon/lib/event_handlers/message_failure.rb
32
- lib/euston-daemons/event_processor_daemon/rake_task.rb
33
- lib/euston-daemons/message_buffer_daemon/config/environment.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
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
- 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
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.1.0'
91
- s.add_dependency 'euston-eventstore', '~> 1.1.0'
92
- s.add_dependency 'euston-rabbitmq', '~> 1.1.0'
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 'jessica', '~> 1.0.0'
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::DaemonComponent.new @log, name, klass, self
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 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
6
+ def run
7
+ next_iteration unless stopped
23
8
  end
24
9
 
25
10
  def stop
26
- @client.stop
27
- @thread[:stop] = true
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 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]
17
+ def next_iteration
18
+ # abstract
51
19
  end
52
20
 
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
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
- AMQP.settings.merge! config
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
- connection = Mongo::Connection.new config[:host], config[:port], :safe => config[:safe], :logger => @logger
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, :read_model_mongodb
40
+ attr_accessor :event_store_mongodb, :projections_mongodb
36
41
  end
37
42
 
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
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,9 @@
1
+ module Euston
2
+ module Daemons
3
+ module Exceptions
4
+ def ignorable_exception? exception
5
+ exception.to_s =~ /clean channel shutdown|clean connection shutdown/
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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
@@ -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