synapse-core 0.5.1 → 0.5.2

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 (101) hide show
  1. checksums.yaml +7 -0
  2. data/lib/synapse.rb +1 -1
  3. data/lib/synapse/command.rb +1 -1
  4. data/lib/synapse/command/command_handler.rb +1 -1
  5. data/lib/synapse/command/mapping.rb +71 -0
  6. data/lib/synapse/command/message.rb +0 -16
  7. data/lib/synapse/command/simple_command_bus.rb +5 -2
  8. data/lib/synapse/common/message.rb +16 -0
  9. data/lib/synapse/configuration.rb +1 -18
  10. data/lib/synapse/configuration/component/command_bus.rb +7 -24
  11. data/lib/synapse/configuration/component/command_bus/simple_command_bus.rb +31 -7
  12. data/lib/synapse/configuration/component/event_bus.rb +3 -8
  13. data/lib/synapse/configuration/component/event_sourcing.rb +11 -8
  14. data/lib/synapse/configuration/component/event_sourcing/aggregate_snapshot_taker.rb +48 -0
  15. data/lib/synapse/configuration/component/event_sourcing/interval_snapshot_policy.rb +33 -0
  16. data/lib/synapse/configuration/component/event_sourcing/repository.rb +36 -1
  17. data/lib/synapse/configuration/component/repository.rb +4 -8
  18. data/lib/synapse/configuration/component/serialization.rb +5 -16
  19. data/lib/synapse/configuration/component/uow.rb +3 -8
  20. data/lib/synapse/configuration/component/upcasting.rb +3 -8
  21. data/lib/synapse/configuration/container_builder.rb +29 -2
  22. data/lib/synapse/configuration/definition_builder.rb +47 -23
  23. data/lib/synapse/domain/message.rb +0 -16
  24. data/lib/synapse/event_bus.rb +1 -1
  25. data/lib/synapse/event_bus/event_listener.rb +1 -1
  26. data/lib/synapse/event_bus/mapping.rb +47 -0
  27. data/lib/synapse/event_sourcing.rb +3 -2
  28. data/lib/synapse/event_sourcing/aggregate_factory.rb +4 -3
  29. data/lib/synapse/event_sourcing/aggregate_root.rb +17 -0
  30. data/lib/synapse/event_sourcing/conflict_resolver.rb +3 -0
  31. data/lib/synapse/event_sourcing/member.rb +34 -6
  32. data/lib/synapse/event_sourcing/repository.rb +17 -0
  33. data/lib/synapse/event_sourcing/snapshot/aggregate_taker.rb +38 -0
  34. data/lib/synapse/event_sourcing/snapshot/policy.rb +27 -0
  35. data/lib/synapse/event_sourcing/snapshot/taker.rb +2 -37
  36. data/lib/synapse/event_sourcing/snapshot/unit_listener.rb +26 -0
  37. data/lib/synapse/event_sourcing/stream_decorator.rb +8 -6
  38. data/lib/synapse/event_store/errors.rb +2 -2
  39. data/lib/synapse/mapping.rb +2 -0
  40. data/lib/synapse/mapping/mapper.rb +75 -0
  41. data/lib/synapse/{wiring/wire.rb → mapping/mapping.rb} +8 -8
  42. data/lib/synapse/process_manager.rb +2 -2
  43. data/lib/synapse/process_manager/mapping/process.rb +44 -0
  44. data/lib/synapse/process_manager/{wiring → mapping}/process_manager.rb +13 -13
  45. data/lib/synapse/process_manager/process.rb +3 -3
  46. data/lib/synapse/repository/locking.rb +14 -8
  47. data/lib/synapse/upcasting/upcaster_chain.rb +2 -2
  48. data/lib/synapse/version.rb +1 -1
  49. data/test/command/{wiring_test.rb → mapping_test.rb} +11 -11
  50. data/test/configuration/component/command_bus/simple_command_bus_test.rb +30 -0
  51. data/test/configuration/component/event_bus/simple_event_bus_test.rb +2 -2
  52. data/test/configuration/component/event_sourcing/repository_test.rb +71 -0
  53. data/test/configuration/component/repository/simple_repository_test.rb +35 -0
  54. data/test/configuration/component/upcasting/upcaster_chain_test.rb +29 -0
  55. data/test/configuration/container_builder_test.rb +4 -6
  56. data/test/event_bus/{wiring_test.rb → mapping_test.rb} +6 -6
  57. data/test/event_sourcing/aggregate_factory_test.rb +5 -1
  58. data/test/event_sourcing/aggregate_root_test.rb +1 -0
  59. data/test/event_sourcing/fixtures.rb +21 -21
  60. data/test/event_sourcing/repository_test.rb +10 -0
  61. data/test/event_sourcing/snapshot/aggregate_taker_test.rb +1 -1
  62. data/test/event_sourcing/snapshot/interval_policy_test.rb +24 -0
  63. data/test/process_manager/{wiring → mapping}/fixtures.rb +7 -8
  64. data/test/process_manager/{wiring → mapping}/process_manager_test.rb +6 -6
  65. data/test/process_manager/{wiring → mapping}/process_test.rb +3 -3
  66. data/test/serialization/converter/chain_test.rb +2 -2
  67. data/test/serialization/converter/factory_test.rb +2 -2
  68. data/test/serialization/converter/identity_test.rb +1 -1
  69. data/test/serialization/converter/json_test.rb +2 -2
  70. data/test/serialization/converter/ox_test.rb +2 -2
  71. data/test/serialization/lazy_object_test.rb +1 -1
  72. data/test/serialization/message/metadata_test.rb +1 -1
  73. data/test/serialization/message/serialization_aware_message_test.rb +5 -5
  74. data/test/serialization/message/serialized_message_builder_test.rb +1 -1
  75. data/test/serialization/message/serialized_message_test.rb +5 -5
  76. data/test/serialization/message/serializer_test.rb +2 -2
  77. data/test/serialization/revision_resolver_test.rb +1 -1
  78. data/test/serialization/serialized_object_test.rb +2 -2
  79. data/test/serialization/serialized_type_test.rb +2 -2
  80. data/test/serialization/serializer/marshal_test.rb +1 -1
  81. data/test/serialization/serializer/oj_test.rb +1 -1
  82. data/test/serialization/serializer/ox_test.rb +2 -2
  83. data/test/serialization/serializer_test.rb +1 -1
  84. data/test/uow/factory_test.rb +1 -1
  85. data/test/uow/outer_commit_listener_test.rb +4 -4
  86. data/test/uow/provider_test.rb +5 -5
  87. data/test/uow/uow_test.rb +19 -17
  88. data/test/upcasting/chain_test.rb +1 -1
  89. data/test/upcasting/data_test.rb +3 -1
  90. metadata +30 -37
  91. data/lib/synapse/command/wiring.rb +0 -47
  92. data/lib/synapse/event_bus/wiring.rb +0 -20
  93. data/lib/synapse/event_sourcing/snapshot/count_stream.rb +0 -86
  94. data/lib/synapse/event_sourcing/snapshot/count_trigger.rb +0 -91
  95. data/lib/synapse/process_manager/wiring/process.rb +0 -27
  96. data/lib/synapse/wiring.rb +0 -3
  97. data/lib/synapse/wiring/message_wiring.rb +0 -76
  98. data/lib/synapse/wiring/wire_registry.rb +0 -61
  99. data/test/event_sourcing/snapshot/integration_test.rb +0 -65
  100. data/test/wiring/wire_registry_test.rb +0 -60
  101. data/test/wiring/wire_test.rb +0 -51
@@ -6,10 +6,24 @@ module Synapse
6
6
  # es_repository :orderbook_repository do
7
7
  # use_aggregate_type TradeEngine::OrderBook
8
8
  # end
9
+ #
10
+ # @example Use an event sourcing repository with snapshotting capability
11
+ # aggregate_snapshot_taker
12
+ #
13
+ # interval_snapshot_policy do
14
+ # use_threshold 50
15
+ # end
16
+ #
17
+ # es_repository :orderbook_repository do
18
+ # use_aggregate_type TradeEngine::OrderBook
19
+ # end
9
20
  class EventSourcingRepositoryDefinitionBuilder < LockingRepositoryDefinitionBuilder
10
- # Convenience method that defines an aggregate factory capable of creating aggregates
21
+ # Convenience method that defines an aggregate factory capable of creating aggregates
11
22
  # of the given type
12
23
  #
24
+ # Definitions have to be created by aggregate factories so that aggregate factories can be
25
+ # registered to an aggregate snapshot taker.
26
+ #
13
27
  # @param [Class] aggregate_type
14
28
  # @return [undefined]
15
29
  def use_aggregate_type(aggregate_type)
@@ -40,13 +54,28 @@ module Synapse
40
54
  @event_store = event_store
41
55
  end
42
56
 
57
+ # @param [Symbol] snapshot_policy
58
+ # @return [undefined]
59
+ def use_snapshot_policy(snapshot_policy)
60
+ @snapshot_policy = snapshot_policy
61
+ end
62
+
63
+ # @param [Symbol] snapshot_taker
64
+ # @return [undefined]
65
+ def use_snapshot_taker(snapshot_taker)
66
+ @snapshot_taker = snapshot_taker
67
+ end
68
+
43
69
  protected
44
70
 
45
71
  # @return [undefined]
46
72
  def populate_defaults
47
73
  super
48
74
 
75
+ use_conflict_resolver :conflict_resolver
49
76
  use_event_store :event_store
77
+ use_snapshot_policy :snapshot_policy
78
+ use_snapshot_taker :snapshot_taker
50
79
 
51
80
  use_factory do
52
81
  aggregate_factory = resolve @aggregate_factory
@@ -54,6 +83,12 @@ module Synapse
54
83
  lock_manager = build_lock_manager
55
84
 
56
85
  repository = EventSourcing::EventSourcingRepository.new aggregate_factory, event_store, lock_manager
86
+
87
+ # Optional dependencies
88
+ repository.conflict_resolver = resolve @conflict_resolver, true
89
+ repository.snapshot_policy = resolve @snapshot_policy, true
90
+ repository.snapshot_taker = resolve @snapshot_taker, true
91
+
57
92
  inject_base_dependencies repository
58
93
  end
59
94
  end
@@ -1,15 +1,11 @@
1
+ require 'synapse/configuration/component/repository/locking_repository'
2
+ require 'synapse/configuration/component/repository/simple_repository'
3
+
1
4
  module Synapse
2
5
  module Configuration
3
6
  class ContainerBuilder
4
7
  # Creates and configures a simple repository
5
- #
6
- # @see SimpleRepositoryDefinitionBuilder
7
- # @param [Symbol] identifier
8
- # @param [Proc] block
9
- # @return [undefined]
10
- def simple_repository(identifier = nil, &block)
11
- with_definition_builder SimpleRepositoryDefinitionBuilder, identifier, &block
12
- end
8
+ builder :simple_repository, SimpleRepositoryDefinitionBuilder
13
9
  end # ContainerBuilder
14
10
  end # Configuration
15
11
  end
@@ -1,25 +1,14 @@
1
+ require 'synapse/configuration/component/serialization/converter_factory'
2
+ require 'synapse/configuration/component/serialization/serializer'
3
+
1
4
  module Synapse
2
5
  module Configuration
3
6
  class ContainerBuilder
4
7
  # Creates and configures a converter factory for serialization
5
- #
6
- # @see ConverterFactoryDefinitionBuilder
7
- # @param [Symbol] identifier
8
- # @param [Proc] block
9
- # @return [undefined]
10
- def converter_factory(identifier = nil, &block)
11
- with_definition_builder ConverterFactoryDefinitionBuilder, identifier, &block
12
- end
8
+ builder :converter_factory, ConverterFactoryDefinitionBuilder
13
9
 
14
10
  # Creates and configures a serializer for partitioning, event storage, etc.
15
- #
16
- # @see SerializerDefinitionBuilder
17
- # @param [Symbol] identifier
18
- # @param [Proc] block
19
- # @return [undefined]
20
- def serializer(identifier = nil, &block)
21
- with_definition_builder SerializerDefinitionBuilder, identifier, &block
22
- end
11
+ builder :serializer, SerializerDefinitionBuilder
23
12
  end # ContainerBuilder
24
13
  end # Configuration
25
14
  end
@@ -1,3 +1,5 @@
1
+ require 'synapse/configuration/component/uow/unit_factory'
2
+
1
3
  module Synapse
2
4
  module Configuration
3
5
  class ContainerBuilder
@@ -9,14 +11,7 @@ module Synapse
9
11
  end
10
12
 
11
13
  # Creates and configures a unit of work factory
12
- #
13
- # @see UnitOfWorkFactoryDefinitionBuilder
14
- # @param [Symbol] identifier
15
- # @param [Proc] block
16
- # @return [undefined]
17
- def unit_factory(identifier = nil, &block)
18
- with_definition_builder UnitOfWorkFactoryDefinitionBuilder, identifier, &block
19
- end
14
+ builder :unit_factory, UnitOfWorkFactoryDefinitionBuilder
20
15
  end # ContainerBuilder
21
16
  end # Configuration
22
17
  end
@@ -1,15 +1,10 @@
1
+ require 'synapse/configuration/component/upcasting/upcaster_chain'
2
+
1
3
  module Synapse
2
4
  module Configuration
3
5
  class ContainerBuilder
4
6
  # Creates and configures an upcaster chain
5
- #
6
- # @see UpcasterChainDefinitionBuilder
7
- # @param [Symbol] identifier
8
- # @param [Proc] block
9
- # @return [undefined]
10
- def upcaster_chain(identifier = nil, &block)
11
- with_definition_builder UpcasterChainDefinitionBuilder, identifier, &block
12
- end
7
+ builder :upcaster_chain, UpcasterChainDefinitionBuilder
13
8
  end # ContainerBuilder
14
9
  end # Configuration
15
10
  end
@@ -19,6 +19,29 @@ module Synapse
19
19
  self.initializers.push initializer
20
20
  end
21
21
 
22
+ # Registers a definition builder that can be used as a shortcut for configuration
23
+ #
24
+ # @example
25
+ # class ContainerBuilder
26
+ # builder :simple_event_bus, SimpleEventBusDefinitionBuilder
27
+ # end
28
+ #
29
+ # @!macro attach
30
+ # @!method $1(identifier = nil, &block)
31
+ # @see $2
32
+ # @param [Symbol] identifier Identifier of the definition
33
+ # @param [Proc] block Executed in the context of the definition builder
34
+ # @return [undefined]
35
+ #
36
+ # @param [Symbol] name
37
+ # @param [Class] builder_class
38
+ # @return [undefined]
39
+ def self.builder(name, builder_class)
40
+ define_method name do |identifier = nil, &block|
41
+ with_definition_builder builder_class, identifier, &block
42
+ end
43
+ end
44
+
22
45
  # @return [Container]
23
46
  attr_reader :container
24
47
 
@@ -36,6 +59,7 @@ module Synapse
36
59
 
37
60
  # Executes the given block in the context of the container builder
38
61
  #
62
+ # @api public
39
63
  # @param [Proc] block
40
64
  # @return [undefined]
41
65
  def build_with(&block)
@@ -54,6 +78,7 @@ module Synapse
54
78
  #
55
79
  # @see #factory If the definition being created is simple
56
80
  # @see DefinitionBuilder
81
+ # @api public
57
82
  # @param [Symbol] id
58
83
  # @param [Proc] block
59
84
  # @return [undefined]
@@ -75,6 +100,7 @@ module Synapse
75
100
  # end
76
101
  #
77
102
  # @see DefinitionBuilder#use_factory
103
+ # @api public
78
104
  # @param [Symbol] id
79
105
  # @param [Object...] args
80
106
  # @param [Proc] block
@@ -96,6 +122,7 @@ module Synapse
96
122
  # executes the block in the context of the definition builder, then finally builds and
97
123
  # registers the definition with this builder's associate container.
98
124
  #
125
+ # @api public
99
126
  # @param [Class] builder_type
100
127
  # @param [Symbol] id
101
128
  # @param [Proc] block
@@ -103,6 +130,6 @@ module Synapse
103
130
  def with_definition_builder(builder_type, id, &block)
104
131
  builder_type.build @container, id, &block
105
132
  end
106
- end
107
- end
133
+ end # ContainerBuilder
134
+ end # Configuration
108
135
  end
@@ -11,8 +11,8 @@ module Synapse
11
11
  # @param [Proc] block
12
12
  # @return [undefined]
13
13
  def self.build(container, id = nil, &block)
14
- builder = self.new container, id
15
- builder.instance_exec(&block) if block
14
+ builder = new container, id
15
+ builder.instance_exec &block if block
16
16
  builder.register_definition
17
17
 
18
18
  builder.id
@@ -31,33 +31,39 @@ module Synapse
31
31
  @id = id.to_sym if id
32
32
  end
33
33
 
34
+ # @api public
34
35
  # @param [Symbol] id
35
36
  # @return [undefined]
36
37
  def identified_by(id)
37
38
  @id = id.to_sym
38
39
  end
39
40
 
41
+ # @api public
40
42
  # @return [undefined]
41
43
  def anonymous
42
44
  identified_by SecureRandom.hex 8
43
45
  end
44
46
 
47
+ # @api public
45
48
  # @param [Symbol...] tags
46
49
  # @return [undefined]
47
50
  def tag(*tags)
48
51
  @tags.merge tags.flatten
49
52
  end
50
53
 
54
+ # @api public
51
55
  # @return [undefined]
52
56
  def as_prototype
53
57
  @prototype = true
54
58
  end
55
59
 
60
+ # @api public
56
61
  # @return [undefined]
57
62
  def as_singleton
58
63
  @prototype = false
59
64
  end
60
65
 
66
+ # @api public
61
67
  # @param [Proc] factory
62
68
  # @return [undefined]
63
69
  def use_factory(&factory)
@@ -66,37 +72,18 @@ module Synapse
66
72
  end
67
73
  end
68
74
 
75
+ # @api public
69
76
  # @param [Object] instance
70
77
  # @return [undefined]
71
78
  def use_instance(instance)
72
79
  @instance = instance
73
80
  end
74
81
 
75
- # If the given value is a symbol, it will be resolved using the container. Otherwise, it
76
- # will be passed through
77
- #
78
- # @param [Object] value
79
- # @return [Object]
80
- def resolve(value, optional = false)
81
- if value.is_a? Symbol
82
- @container.resolve value, optional
83
- else
84
- value
85
- end
86
- end
87
-
88
- # Resolves all services that have the given tag
89
- #
90
- # @param [Symbol] tag
91
- # @return [Array]
92
- def resolve_tagged(tag)
93
- @container.resolve_tagged tag
94
- end
95
-
96
82
  # Convenience method for building composite services
97
83
  #
98
84
  # The given block will be executed in the context of the definition builder
99
85
  #
86
+ # @api public
100
87
  # @param [Class] builder_type Defaults to DefinitionBuilder
101
88
  # @param [Proc] block
102
89
  # @return [Symbol] The identifier of the newly created service
@@ -124,8 +111,45 @@ module Synapse
124
111
  # @return [undefined]
125
112
  def populate_defaults; end
126
113
 
114
+ # Injects any configured dependencies into the given object
115
+ #
116
+ # @api public
117
+ # @param [Dependent] object
118
+ # @return [Dependent]
119
+ def inject_into(object)
120
+ @container.inject_into object
121
+ object
122
+ end
123
+
124
+ # If the given value is a symbol, it will be resolved using the container. Otherwise, it
125
+ # will be passed through
126
+ #
127
+ # @api public
128
+ # @raise [ConfigurationError] If value is required but was not set
129
+ # @param [Object] value
130
+ # @return [Object]
131
+ def resolve(value, optional = false)
132
+ if value.is_a? Symbol
133
+ @container.resolve value, optional
134
+ elsif value.nil? and not optional
135
+ raise ConfigurationError, 'Value was not set'
136
+ else
137
+ value
138
+ end
139
+ end
140
+
141
+ # Resolves all services that have the given tag
142
+ #
143
+ # @api public
144
+ # @param [Symbol] tag
145
+ # @return [Array]
146
+ def resolve_tagged(tag)
147
+ @container.resolve_tagged tag
148
+ end
149
+
127
150
  # Resolves any services with the given tag and yields them
128
151
  #
152
+ # @api public
129
153
  # @yield [Object]
130
154
  # @param [Symbol] tag
131
155
  # @return [undefined]
@@ -23,22 +23,6 @@ module Synapse
23
23
  EventMessageBuilder
24
24
  end
25
25
 
26
- # Creates an event message using the given event object
27
- #
28
- # If the given object is an event message, it will be returned unchanged.
29
- #
30
- # @param [Object] event
31
- # @return [EventMessage]
32
- def self.as_message(event)
33
- unless event.is_a? EventMessage
34
- event = self.build do |builder|
35
- builder.payload = event
36
- end
37
- end
38
-
39
- event
40
- end
41
-
42
26
  protected
43
27
 
44
28
  # @param [EventMessageBuilder] builder
@@ -1,5 +1,5 @@
1
1
  require 'synapse/event_bus/event_bus'
2
2
  require 'synapse/event_bus/event_listener'
3
3
  require 'synapse/event_bus/event_publisher'
4
+ require 'synapse/event_bus/mapping'
4
5
  require 'synapse/event_bus/simple_event_bus'
5
- require 'synapse/event_bus/wiring'
@@ -3,7 +3,7 @@ module Synapse
3
3
  # Represents a listener that can be notified of events from an event bus. Implementations are
4
4
  # highly discouraged from throwing exceptions.
5
5
  #
6
- # Consider using the event listener mixin that uses message wiring.
6
+ # Consider using the event listener mixin that uses the mapping DSL.
7
7
  #
8
8
  # @abstract
9
9
  module EventListener
@@ -0,0 +1,47 @@
1
+ module Synapse
2
+ module EventBus
3
+ # Mixin for an event listener that wishes to use the mapping DSL
4
+ #
5
+ # @example
6
+ # class OrderBookManagementListener
7
+ # include MappingEventListener
8
+ #
9
+ # map_event UserRegistered do |event|
10
+ # # ...
11
+ # end
12
+ #
13
+ # map_event UserBanned, :to => :on_banned
14
+ # end
15
+ module MappingEventListener
16
+ extend ActiveSupport::Concern
17
+ include EventListener
18
+
19
+ included do
20
+ # @return [Mapping::Mapper]
21
+ class_attribute :event_mapper
22
+ self.event_mapper = Mapping::Mapper.new true
23
+ end
24
+
25
+ module ClassMethods
26
+ # @see Mapper#map
27
+ # @param [Class] type
28
+ # @param [Object...] args
29
+ # @param [Proc] block
30
+ # @return [undefined]
31
+ def map_event(type, *args, &block)
32
+ event_mapper.map type, *args, &block
33
+ end
34
+ end
35
+
36
+ # @param [EventMessage] event
37
+ # @return [undefined]
38
+ def notify(event)
39
+ mapping = event_mapper.mapping_for event.payload_type
40
+
41
+ return unless mapping
42
+
43
+ mapping.invoke self, event.payload
44
+ end
45
+ end # MappingEventListener
46
+ end # EventBus
47
+ end