synapse-core 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/lib/synapse/command/async_command_bus.rb +3 -5
  2. data/lib/synapse/common.rb +0 -1
  3. data/lib/synapse/configuration/component/command_bus/async_command_bus.rb +3 -2
  4. data/lib/synapse/configuration/component/{mixin → shared}/thread_pool.rb +10 -8
  5. data/lib/synapse/configuration/dependent.rb +2 -2
  6. data/lib/synapse/configuration/ext.rb +58 -29
  7. data/lib/synapse/configuration.rb +1 -1
  8. data/lib/synapse/domain/aggregate_root.rb +43 -19
  9. data/lib/synapse/domain/errors.rb +9 -0
  10. data/lib/synapse/domain/event_container.rb +3 -3
  11. data/lib/synapse/domain/message.rb +2 -2
  12. data/lib/synapse/domain/message_builder.rb +2 -2
  13. data/lib/synapse/domain/simple_stream.rb +39 -0
  14. data/lib/synapse/domain/stream.rb +2 -41
  15. data/lib/synapse/domain.rb +3 -0
  16. data/lib/synapse/event_sourcing/aggregate_root.rb +102 -2
  17. data/lib/synapse/event_sourcing/caching.rb +1 -1
  18. data/lib/synapse/event_sourcing/entity.rb +2 -2
  19. data/lib/synapse/event_sourcing/member.rb +3 -13
  20. data/lib/synapse/event_sourcing/repository.rb +9 -2
  21. data/lib/synapse/event_sourcing/snapshot/taker.rb +2 -2
  22. data/lib/synapse/mapping/mapping.rb +2 -2
  23. data/lib/synapse/process_manager/simple_process_manager.rb +1 -0
  24. data/lib/synapse/rails/injection_helper.rb +23 -0
  25. data/lib/synapse/railtie.rb +17 -0
  26. data/lib/synapse/repository/lock_manager.rb +3 -3
  27. data/lib/synapse/uow/listener.rb +2 -2
  28. data/lib/synapse/uow/listener_collection.rb +7 -51
  29. data/lib/synapse/version.rb +1 -1
  30. data/lib/synapse-core.rb +1 -0
  31. data/lib/synapse.rb +3 -0
  32. data/test/command/async_command_bus_test.rb +8 -11
  33. data/test/configuration/component/command_bus/async_command_bus_test.rb +7 -6
  34. data/test/configuration/component/serialization/serializer_test.rb +2 -2
  35. data/test/configuration/fixtures/dependent.rb +1 -1
  36. data/test/rails/injection_helper_test.rb +27 -0
  37. data/test/serialization/converter/ox_test.rb +2 -2
  38. data/test/serialization/serializer/oj_test.rb +1 -1
  39. data/test/serialization/serializer/ox_test.rb +1 -1
  40. data/test/test_helper.rb +8 -9
  41. data/test/uow/uow_test.rb +2 -2
  42. metadata +221 -222
  43. data/lib/synapse/common/concurrency/executor.rb +0 -13
  44. data/test/support/countdown_latch.rb +0 -18
@@ -62,7 +62,7 @@ module Synapse
62
62
  aggregate.initialize_from_stream stream
63
63
 
64
64
  if aggregate.deleted?
65
- raise AggregateDeletedError
65
+ raise AggregateDeletedError.new type_identifier, aggregate_id
66
66
  end
67
67
 
68
68
  if expected_version and @conflict_resolver.nil?
@@ -138,6 +138,13 @@ module Synapse
138
138
  end
139
139
 
140
140
  # Raised when an aggregate has been found but it was marked for deletion
141
- class AggregateDeletedError < Repository::AggregateNotFoundError; end
141
+ class AggregateDeletedError < Repository::AggregateNotFoundError
142
+ # @param [String] type_identifier
143
+ # @param [Object] aggregate_id
144
+ # @return [undefined]
145
+ def initialize(type_identifier, aggregate_id)
146
+ super 'Aggregate marked for deletion [%s] [%s]' % [type_identifier, aggregate_id]
147
+ end
148
+ end
142
149
  end
143
150
  end
@@ -10,12 +10,12 @@ module Synapse
10
10
  # @return [SnapshotEventStore]
11
11
  attr_accessor :event_store
12
12
 
13
- # @return [Executor]
13
+ # @return [Contender::Executor]
14
14
  attr_accessor :executor
15
15
 
16
16
  # @return [undefined]
17
17
  def initialize
18
- @executor = DirectExecutor.new
18
+ @executor = Contender::DirectExecutor.new
19
19
  end
20
20
 
21
21
  # Schedules a snapshot to be taken for an aggregate of the given type and with the given
@@ -55,6 +55,6 @@ module Synapse
55
55
  def hash
56
56
  @type.hash
57
57
  end
58
- end
59
- end
58
+ end # Mapping
59
+ end # Mapping
60
60
  end
@@ -4,6 +4,7 @@ module Synapse
4
4
  class SimpleProcessManager < ProcessManager
5
5
  # @return [Array] Types of events that will always result in the creation of a process
6
6
  attr_accessor :always_create_events
7
+
7
8
  # @return [Array] Types of events that will result in the creation of a process if one
8
9
  # doesn't already exist
9
10
  attr_accessor :optionally_create_events
@@ -0,0 +1,23 @@
1
+ module Synapse
2
+ module Rails
3
+ # Mixin for an action controller in Rails that adds dependency injection
4
+ module InjectionHelper
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_filter :inject_dependencies
9
+ end
10
+
11
+ # Performs one-time dependency injection before an action is called
12
+ # @return [undefined]
13
+ def inject_dependencies
14
+ return if @_dependencies_injected
15
+
16
+ container = Synapse.container
17
+ container.inject_into self
18
+
19
+ @_dependencies_injected = true
20
+ end
21
+ end # InjectionHelper
22
+ end # Rails
23
+ end
@@ -0,0 +1,17 @@
1
+ module Synapse
2
+ # Simple integration between the Synapse framework and Rails 3.2+
3
+ class Railtie < Rails::Railtie
4
+ # Set the name of the Railtie
5
+ railtie_name :synapse
6
+
7
+ # Controllers will get dependencies injected automatically
8
+ initializer 'synapse.include_controller_mixins' do
9
+ ActionController::Base.class_eval do
10
+ include Synapse::Configuration::Dependent
11
+ include Synapse::Rails::InjectionHelper
12
+ end
13
+ end
14
+ end # Railtie
15
+ end
16
+
17
+ require 'synapse/rails/injection_helper'
@@ -26,7 +26,7 @@ module Synapse
26
26
  # @param [Object] aggregate_id
27
27
  # @return [undefined]
28
28
  def release_lock(aggregate_id); end
29
- end
29
+ end # LockManager
30
30
 
31
31
  # Implementation of a lock manager that does no locking
32
32
  class NullLockManager < LockManager
@@ -35,6 +35,6 @@ module Synapse
35
35
  def validate_lock(aggregate)
36
36
  true
37
37
  end
38
- end
39
- end
38
+ end # NullLockManager
39
+ end # Repository
40
40
  end
@@ -74,6 +74,6 @@ module Synapse
74
74
  # @param [UnitOfWork] unit
75
75
  # @return [undefined]
76
76
  def on_cleanup(unit); end
77
- end
78
- end
77
+ end # UnitOfWorkListener
78
+ end # UnitOfWork
79
79
  end
@@ -22,10 +22,7 @@ module Synapse
22
22
  # @param [UnitOfWorkListener] listener
23
23
  # @return [undefined]
24
24
  def push(listener)
25
- if @logger.debug?
26
- @logger.debug 'Registering listener [%s]' % listener.class
27
- end
28
-
25
+ @logger.debug 'Registering listener [%s]' % listener.class
29
26
  @listeners.push listener
30
27
  end
31
28
 
@@ -34,17 +31,10 @@ module Synapse
34
31
  # @param [UnitOfWork] unit
35
32
  # @return [undefined]
36
33
  def on_start(unit)
37
- @logger.debug 'Notifying listeners that unit of work is starting'
38
-
39
34
  @listeners.each do |listener|
40
- if @logger.debug?
41
- @logger.debug 'Notifying [%s] of start' % listener.class
42
- end
43
-
35
+ @logger.debug 'Notifying [%s] of start' % listener.class
44
36
  listener.on_start unit
45
37
  end
46
-
47
- @logger.debug 'Listeners successfully notified'
48
38
  end
49
39
 
50
40
  # @param [UnitOfWork] unit
@@ -63,78 +53,46 @@ module Synapse
63
53
  # @param [Hash<EventBus, Array>] events
64
54
  # @return [undefined]
65
55
  def on_prepare_commit(unit, aggregates, events)
66
- @logger.debug 'Notifying listeners that commit was requested'
67
-
68
56
  @listeners.each do |listener|
69
- if @logger.debug?
70
- @logger.debug 'Notifying [%s] of commit' % listener.class
71
- end
72
-
57
+ @logger.debug 'Notifying [%s] of commit' % listener.class
73
58
  listener.on_prepare_commit unit, aggregates, events
74
59
  end
75
-
76
- @logger.debug 'Listeners successfully notified'
77
60
  end
78
61
 
79
62
  # @param [UnitOfWork] unit
80
63
  # @param [Object] transaction
81
64
  # @return [undefined]
82
65
  def on_prepare_transaction_commit(unit, transaction)
83
- @logger.debug 'Notifying listeners that transactional commit was requested'
84
-
85
66
  @listeners.each do |listener|
86
- if @logger.debug?
87
- @logger.debug 'Notifying [%s] of transactional commit' % listener.class
88
- end
89
-
67
+ @logger.debug 'Notifying [%s] of transactional commit' % listener.class
90
68
  listener.on_prepare_transaction_commit unit, transaction
91
69
  end
92
-
93
- @logger.debug 'Listeners successfully notified'
94
70
  end
95
71
 
96
72
  # @param [UnitOfWork] unit
97
73
  # @return [undefined]
98
74
  def after_commit(unit)
99
- @logger.debug 'Notifying listeners that commit has finished'
100
-
101
75
  @listeners.reverse_each do |listener|
102
- if @logger.debug?
103
- @logger.debug 'Notifying [%s] of finished commit' % listener.class
104
- end
105
-
76
+ @logger.debug 'Notifying [%s] of finished commit' % listener.class
106
77
  listener.after_commit unit
107
78
  end
108
-
109
- @logger.debug 'Listeners successfully notified'
110
79
  end
111
80
 
112
81
  # @param [UnitOfWork] unit
113
82
  # @param [Error] cause
114
83
  # @return [undefined]
115
84
  def on_rollback(unit, cause = nil)
116
- @logger.debug 'Notifying listeners of rollback'
117
-
118
85
  @listeners.reverse_each do |listener|
119
- if @logger.debug?
120
- @logger.debug 'Notifying [%s] of rollback' % listener.class
121
- end
122
-
86
+ @logger.debug 'Notifying [%s] of rollback' % listener.class
123
87
  listener.on_rollback unit, cause
124
88
  end
125
-
126
- @logger.debug 'Listeners successfully notified'
127
89
  end
128
90
 
129
91
  # @param [UnitOfWork] unit
130
92
  # @return [undefined]
131
93
  def on_cleanup(unit)
132
- @logger.debug 'Notifying listeners of cleanup'
133
-
134
94
  @listeners.reverse_each do |listener|
135
- if @logger.debug?
136
- @logger.debug 'Notifying [%s] of cleanup' % listener.class
137
- end
95
+ @logger.debug 'Notifying [%s] of cleanup' % listener.class
138
96
 
139
97
  begin
140
98
  listener.on_cleanup unit
@@ -143,8 +101,6 @@ module Synapse
143
101
  @logger.warn 'Listener raised an exception during cleanup: %s' % exception.inspect
144
102
  end
145
103
  end
146
-
147
- @logger.debug 'Listeners successfully notified'
148
104
  end
149
105
  end # UnitOfWorkListenerCollection
150
106
  end # UnitOfWork
@@ -1,3 +1,3 @@
1
1
  module Synapse
2
- VERSION = '0.5.4'
2
+ VERSION = '0.5.5'
3
3
  end
@@ -0,0 +1 @@
1
+ require 'synapse'
data/lib/synapse.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'active_support'
2
2
  require 'active_support/core_ext'
3
+ require 'contender'
3
4
  require 'forwardable'
4
5
  require 'logging'
5
6
  require 'set'
@@ -29,3 +30,5 @@ module Synapse
29
30
  autoload :ProcessManager
30
31
  autoload :Upcasting
31
32
  end
33
+
34
+ require 'synapse/railtie' if defined? Rails
@@ -1,5 +1,4 @@
1
1
  require 'test_helper'
2
- require 'support/countdown_latch'
3
2
 
4
3
  module Synapse
5
4
  module Command
@@ -9,14 +8,16 @@ module Synapse
9
8
  unit_factory = UnitOfWork::UnitOfWorkFactory.new unit_provider
10
9
 
11
10
  @bus = AsynchronousCommandBus.new unit_factory
12
- @bus.thread_pool = Thread.pool 2
11
+ @bus.thread_pool = Contender::Pool::ThreadPoolExecutor.new
12
+ @bus.thread_pool.start
13
13
  end
14
14
 
15
15
  should 'be able to dispatch commands asynchronously using a thread pool' do
16
16
  x = 5 # Number of commands to dispatch
17
17
 
18
18
  command = CommandMessage.as_message TestCommand.new
19
- handler = TestAsyncHandler.new x
19
+ latch = Contender::CountdownLatch.new x
20
+ handler = TestAsyncHandler.new latch
20
21
 
21
22
  @bus.subscribe TestCommand, handler
22
23
 
@@ -24,23 +25,19 @@ module Synapse
24
25
  @bus.dispatch command
25
26
  end
26
27
 
27
- wait_until do
28
- handler.latch.count == 0
29
- end
28
+ assert latch.await 5
30
29
 
31
30
  @bus.shutdown
32
31
  end
33
32
  end
34
33
 
35
34
  class TestAsyncHandler
36
- attr_reader :latch
37
-
38
- def initialize(x)
39
- @latch = CountdownLatch.new x
35
+ def initialize(latch)
36
+ @latch = latch
40
37
  end
41
38
 
42
39
  def handle(command, unit)
43
- @latch.countdown!
40
+ @latch.countdown
44
41
  end
45
42
  end
46
43
 
@@ -16,20 +16,21 @@ module Synapse
16
16
  assert command_bus.is_a? Command::AsynchronousCommandBus
17
17
 
18
18
  thread_pool = command_bus.thread_pool
19
- assert_equal 4, thread_pool.min
20
- assert_equal 4, thread_pool.max
19
+ assert_instance_of Contender::Pool::ThreadPoolExecutor, thread_pool
20
+ assert thread_pool.active?
21
+ thread_pool.shutdown
21
22
  end
22
23
 
23
- should 'build with a custom thread pool size' do
24
+ should 'build with a custom thread pool options' do
24
25
  @builder.async_command_bus do
25
- use_threads 2, 8
26
+ use_pool_options size: 4, non_block: true
26
27
  end
27
28
 
28
29
  command_bus = @container.resolve :command_bus
29
30
 
30
31
  thread_pool = command_bus.thread_pool
31
- assert_equal 2, thread_pool.min
32
- assert_equal 8, thread_pool.max
32
+ assert thread_pool.active?
33
+ thread_pool.shutdown
33
34
  end
34
35
  end
35
36
  end
@@ -40,7 +40,7 @@ module Synapse
40
40
  end
41
41
 
42
42
  should 'build with OxSerializer' do
43
- skip 'Ox not supported on JRuby' if defined? JRUBY_VERSION
43
+ omit 'Ox not supported on JRuby' if defined? JRUBY_VERSION
44
44
 
45
45
  serialize_options = { :circular => true }
46
46
 
@@ -56,7 +56,7 @@ module Synapse
56
56
  end
57
57
 
58
58
  should 'build with OjSerializer' do
59
- skip 'Oj not supported on JRuby' if defined? JRUBY_VERSION
59
+ omit 'Oj not supported on JRuby' if defined? JRUBY_VERSION
60
60
 
61
61
  serialize_options = { :indent => 2, :circular => true }
62
62
  deserialize_options = { :symbol_keys => true }
@@ -4,7 +4,7 @@ module Synapse
4
4
  include Dependent
5
5
 
6
6
  depends_on :service_a
7
- depends_on :service_b, :attribute => :some_service
7
+ depends_on :service_b, :as => :some_service
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ require 'rails'
4
+ require 'synapse/railtie'
5
+
6
+ module Synapse
7
+ module Rails
8
+ class InjectionHelperTest < Test::Unit::TestCase
9
+
10
+ def setup
11
+ @controller_class = Class.new
12
+ @controller = @controller_class.new
13
+ mock(@controller_class).before_filter(:inject_dependencies)
14
+ @controller_class.send :include, InjectionHelper
15
+ end
16
+
17
+ should 'inject dependencies only once' do
18
+ container_mock = mock(Synapse).container.mock!
19
+ container_mock.inject_into(@controller)
20
+
21
+ @controller.inject_dependencies
22
+ @controller.inject_dependencies
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -4,7 +4,7 @@ module Synapse
4
4
  module Serialization
5
5
  class OxDocumentToXmlConverterTest < Test::Unit::TestCase
6
6
  def setup
7
- skip 'Ox not supported on JRuby' if defined? JRUBY_VERSION
7
+ omit 'Ox not supported on JRuby' if defined? JRUBY_VERSION
8
8
  end
9
9
 
10
10
  should 'convert an Ox document to an XML string' do
@@ -22,7 +22,7 @@ module Synapse
22
22
 
23
23
  class XmlToOxDocumentConverterTest < Test::Unit::TestCase
24
24
  def setup
25
- skip 'Ox not supported on JRuby' if defined? JRUBY_VERSION
25
+ omit 'Ox not supported on JRuby' if defined? JRUBY_VERSION
26
26
  end
27
27
 
28
28
  should 'convert an XML string to an Ox document' do
@@ -6,7 +6,7 @@ module Synapse
6
6
 
7
7
  class OjSerializerTest < Test::Unit::TestCase
8
8
  def setup
9
- skip 'Oj not supported on JRuby' if defined? JRUBY_VERSION
9
+ omit 'Oj not supported on JRuby' if defined? JRUBY_VERSION
10
10
  end
11
11
 
12
12
  should 'support serializing and deserializing content' do
@@ -6,7 +6,7 @@ module Synapse
6
6
 
7
7
  class OxSerializerTest < Test::Unit::TestCase
8
8
  def setup
9
- skip 'Ox not supported on JRuby' if defined? JRUBY_VERSION
9
+ omit 'Ox not supported on JRuby' if defined? JRUBY_VERSION
10
10
 
11
11
  @serializer = OxSerializer.new ConverterFactory.new
12
12
  end
data/test/test_helper.rb CHANGED
@@ -8,19 +8,18 @@ else
8
8
  end
9
9
  end
10
10
 
11
- require 'pp'
11
+ # Need this for Contender, since we get it from GitHub for now
12
+ require 'bundler/setup'
13
+
12
14
  require 'synapse'
15
+
16
+ require 'pp'
13
17
  require 'test/unit'
14
- require 'shoulda/context'
15
- require 'rr'
18
+ require 'test/unit/rr'
19
+
16
20
  require 'timecop'
21
+ require 'shoulda/context'
17
22
 
18
23
  require 'test_ext'
19
24
 
20
- # I guess RR broke
21
- # http://stackoverflow.com/questions/3657972
22
- unless defined? Test::Unit::AssertionFailedError
23
- Test::Unit::AssertionFailedError = ActiveSupport::TestCase::Assertion
24
- end
25
-
26
25
  ActiveSupport::Autoload.eager_autoload!
data/test/uow/uow_test.rb CHANGED
@@ -159,8 +159,8 @@ module Synapse
159
159
 
160
160
  should 'rollback if an aggregate storage callback raises an exception' do
161
161
  aggregate_root = Object.new
162
- mock(aggregate_root).add_registration_listener
163
- mock(aggregate_root).id
162
+ stub(aggregate_root).add_registration_listener
163
+ stub(aggregate_root).id
164
164
 
165
165
  event_bus = Object.new
166
166
  cause = TestError.new