synapse-core 0.1.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.
- data/lib/synapse.rb +351 -0
- data/lib/synapse/command/command_bus.rb +45 -0
- data/lib/synapse/command/command_callback.rb +18 -0
- data/lib/synapse/command/command_filter.rb +17 -0
- data/lib/synapse/command/command_handler.rb +13 -0
- data/lib/synapse/command/dispatch_interceptor.rb +16 -0
- data/lib/synapse/command/duplication.rb +43 -0
- data/lib/synapse/command/errors.rb +27 -0
- data/lib/synapse/command/filters/validation.rb +32 -0
- data/lib/synapse/command/gateway.rb +34 -0
- data/lib/synapse/command/interceptor_chain.rb +31 -0
- data/lib/synapse/command/interceptors/serialization.rb +35 -0
- data/lib/synapse/command/message.rb +19 -0
- data/lib/synapse/command/rollback_policy.rb +22 -0
- data/lib/synapse/command/simple_command_bus.rb +138 -0
- data/lib/synapse/command/wiring.rb +47 -0
- data/lib/synapse/domain/aggregate_root.rb +121 -0
- data/lib/synapse/domain/event_container.rb +127 -0
- data/lib/synapse/domain/message.rb +82 -0
- data/lib/synapse/domain/message_builder.rb +34 -0
- data/lib/synapse/domain/stream.rb +108 -0
- data/lib/synapse/duplication.rb +60 -0
- data/lib/synapse/errors.rb +13 -0
- data/lib/synapse/event_bus/event_bus.rb +40 -0
- data/lib/synapse/event_bus/event_listener.rb +16 -0
- data/lib/synapse/event_bus/event_listener_proxy.rb +12 -0
- data/lib/synapse/event_bus/simple_event_bus.rb +69 -0
- data/lib/synapse/event_bus/wiring.rb +23 -0
- data/lib/synapse/event_sourcing/aggregate_factory.rb +69 -0
- data/lib/synapse/event_sourcing/aggregate_root.rb +104 -0
- data/lib/synapse/event_sourcing/conflict_resolver.rb +80 -0
- data/lib/synapse/event_sourcing/entity.rb +64 -0
- data/lib/synapse/event_sourcing/member.rb +72 -0
- data/lib/synapse/event_sourcing/repository.rb +119 -0
- data/lib/synapse/event_sourcing/snapshot/count_stream.rb +86 -0
- data/lib/synapse/event_sourcing/snapshot/count_trigger.rb +91 -0
- data/lib/synapse/event_sourcing/snapshot/taker.rb +73 -0
- data/lib/synapse/event_sourcing/storage_listener.rb +34 -0
- data/lib/synapse/event_sourcing/stream_decorator.rb +25 -0
- data/lib/synapse/event_store/errors.rb +16 -0
- data/lib/synapse/event_store/event_store.rb +43 -0
- data/lib/synapse/event_store/in_memory.rb +59 -0
- data/lib/synapse/event_store/mongo/cursor_event_stream.rb +63 -0
- data/lib/synapse/event_store/mongo/event_store.rb +86 -0
- data/lib/synapse/event_store/mongo/per_commit_strategy.rb +253 -0
- data/lib/synapse/event_store/mongo/per_event_strategy.rb +143 -0
- data/lib/synapse/event_store/mongo/storage_strategy.rb +113 -0
- data/lib/synapse/event_store/mongo/template.rb +73 -0
- data/lib/synapse/identifier.rb +23 -0
- data/lib/synapse/message.rb +101 -0
- data/lib/synapse/message_builder.rb +38 -0
- data/lib/synapse/process_manager/correlation.rb +32 -0
- data/lib/synapse/process_manager/correlation_resolver.rb +14 -0
- data/lib/synapse/process_manager/correlation_set.rb +58 -0
- data/lib/synapse/process_manager/process.rb +71 -0
- data/lib/synapse/repository/errors.rb +26 -0
- data/lib/synapse/repository/lock_manager.rb +40 -0
- data/lib/synapse/repository/locking.rb +97 -0
- data/lib/synapse/repository/pessimistic_lock_manager.rb +61 -0
- data/lib/synapse/repository/repository.rb +109 -0
- data/lib/synapse/serialization/converter.rb +39 -0
- data/lib/synapse/serialization/converter/chain.rb +45 -0
- data/lib/synapse/serialization/converter/factory.rb +68 -0
- data/lib/synapse/serialization/converter/identity.rb +29 -0
- data/lib/synapse/serialization/converter/json.rb +31 -0
- data/lib/synapse/serialization/converter/ox.rb +31 -0
- data/lib/synapse/serialization/errors.rb +12 -0
- data/lib/synapse/serialization/lazy_object.rb +61 -0
- data/lib/synapse/serialization/message/data.rb +25 -0
- data/lib/synapse/serialization/message/metadata.rb +13 -0
- data/lib/synapse/serialization/message/serialization_aware.rb +17 -0
- data/lib/synapse/serialization/message/serialization_aware_message.rb +66 -0
- data/lib/synapse/serialization/message/serialized_message.rb +201 -0
- data/lib/synapse/serialization/message/serialized_message_builder.rb +64 -0
- data/lib/synapse/serialization/message/serialized_object_cache.rb +50 -0
- data/lib/synapse/serialization/message/serializer.rb +47 -0
- data/lib/synapse/serialization/revision_resolver.rb +30 -0
- data/lib/synapse/serialization/serialized_object.rb +37 -0
- data/lib/synapse/serialization/serialized_type.rb +31 -0
- data/lib/synapse/serialization/serializer.rb +98 -0
- data/lib/synapse/serialization/serializer/marshal.rb +32 -0
- data/lib/synapse/serialization/serializer/oj.rb +34 -0
- data/lib/synapse/serialization/serializer/ox.rb +31 -0
- data/lib/synapse/uow/factory.rb +28 -0
- data/lib/synapse/uow/listener.rb +79 -0
- data/lib/synapse/uow/listener_collection.rb +93 -0
- data/lib/synapse/uow/nesting.rb +262 -0
- data/lib/synapse/uow/provider.rb +71 -0
- data/lib/synapse/uow/storage_listener.rb +14 -0
- data/lib/synapse/uow/transaction_manager.rb +27 -0
- data/lib/synapse/uow/uow.rb +178 -0
- data/lib/synapse/upcasting/chain.rb +78 -0
- data/lib/synapse/upcasting/context.rb +58 -0
- data/lib/synapse/upcasting/data.rb +30 -0
- data/lib/synapse/upcasting/single_upcaster.rb +57 -0
- data/lib/synapse/upcasting/upcaster.rb +55 -0
- data/lib/synapse/version.rb +3 -0
- data/lib/synapse/wiring/message_wiring.rb +41 -0
- data/lib/synapse/wiring/wire.rb +55 -0
- data/lib/synapse/wiring/wire_registry.rb +61 -0
- data/test/command/duplication_test.rb +54 -0
- data/test/command/gateway_test.rb +25 -0
- data/test/command/interceptor_chain_test.rb +26 -0
- data/test/command/serialization_test.rb +37 -0
- data/test/command/simple_command_bus_test.rb +141 -0
- data/test/command/validation_test.rb +42 -0
- data/test/command/wiring_test.rb +73 -0
- data/test/domain/aggregate_root_test.rb +57 -0
- data/test/domain/fixtures.rb +31 -0
- data/test/domain/message_test.rb +61 -0
- data/test/domain/stream_test.rb +35 -0
- data/test/duplication_test.rb +40 -0
- data/test/event_bus/wiring_test.rb +46 -0
- data/test/event_sourcing/aggregate_factory_test.rb +28 -0
- data/test/event_sourcing/aggregate_root_test.rb +76 -0
- data/test/event_sourcing/entity_test.rb +34 -0
- data/test/event_sourcing/fixtures.rb +85 -0
- data/test/event_sourcing/repository_test.rb +102 -0
- data/test/event_sourcing/snapshot/aggregate_taker_test.rb +39 -0
- data/test/event_sourcing/snapshot/deferred_taker_test.rb +19 -0
- data/test/event_sourcing/snapshot/integration_test.rb +65 -0
- data/test/event_sourcing/storage_listener_test.rb +77 -0
- data/test/event_store/in_memory_test.rb +47 -0
- data/test/process_manager/correlation_set_test.rb +49 -0
- data/test/process_manager/correlation_test.rb +24 -0
- data/test/process_manager/process_test.rb +52 -0
- data/test/repository/locking_test.rb +101 -0
- data/test/serialization/converter/factory_test.rb +33 -0
- data/test/serialization/converter/identity_test.rb +17 -0
- data/test/serialization/converter/json_test.rb +31 -0
- data/test/serialization/converter/ox_test.rb +40 -0
- data/test/serialization/fixtures.rb +17 -0
- data/test/serialization/lazy_object_test.rb +32 -0
- data/test/serialization/message/metadata_test.rb +19 -0
- data/test/serialization/message/serialization_aware_message_test.rb +88 -0
- data/test/serialization/message/serialized_message_builder_test.rb +41 -0
- data/test/serialization/message/serialized_message_test.rb +140 -0
- data/test/serialization/message/serializer_test.rb +50 -0
- data/test/serialization/revision_resolver_test.rb +12 -0
- data/test/serialization/serialized_object_test.rb +36 -0
- data/test/serialization/serialized_type_test.rb +27 -0
- data/test/serialization/serializer/marshal_test.rb +22 -0
- data/test/serialization/serializer/oj_test.rb +24 -0
- data/test/serialization/serializer/ox_test.rb +36 -0
- data/test/serialization/serializer_test.rb +20 -0
- data/test/test_helper.rb +19 -0
- data/test/uow/factory_test.rb +23 -0
- data/test/uow/outer_commit_listener_test.rb +50 -0
- data/test/uow/provider_test.rb +70 -0
- data/test/uow/uow_test.rb +337 -0
- data/test/upcasting/chain_test.rb +29 -0
- data/test/upcasting/fixtures.rb +66 -0
- data/test/wiring/wire_registry_test.rb +60 -0
- data/test/wiring/wire_test.rb +51 -0
- metadata +263 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Convenience implementation of serialized object containing metadata
|
|
4
|
+
class SerializedMetadata < SerializedObject
|
|
5
|
+
# @param [Object] content
|
|
6
|
+
# @param [Class] content_type
|
|
7
|
+
# @return [undefined]
|
|
8
|
+
def initialize(content, content_type)
|
|
9
|
+
super(content, content_type, SerializedType.new(Hash.to_s, nil))
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Contract for message implementations that are aware of the serialization component and
|
|
4
|
+
# can provide optimization for the serialization process
|
|
5
|
+
module SerializationAware
|
|
6
|
+
# @param [Serializer] serializer
|
|
7
|
+
# @param [Class] expected_type
|
|
8
|
+
# @return [SerializedObject]
|
|
9
|
+
def serialize_metadata(serializer, expected_type); end
|
|
10
|
+
|
|
11
|
+
# @param [Serializer] serializer
|
|
12
|
+
# @param [Class] expected_type
|
|
13
|
+
# @return [SerializedObject]
|
|
14
|
+
def serialize_payload(serializer, expected_type); end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Decorator for an event message that adds serialization awareness
|
|
4
|
+
#
|
|
5
|
+
# Any serialization that occurs on the metadata or payload of this message will be
|
|
6
|
+
# cached so that if a message is serialized more than once, the serialization process will
|
|
7
|
+
# only occur once.
|
|
8
|
+
class SerializationAwareEventMessage
|
|
9
|
+
extend Forwardable
|
|
10
|
+
include SerializationAware
|
|
11
|
+
|
|
12
|
+
# @param [EventMessage] message
|
|
13
|
+
# @return [SerializationAwareEventMessage]
|
|
14
|
+
def self.decorate(message)
|
|
15
|
+
if message.is_a? SerializationAware
|
|
16
|
+
return message
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
self.new message
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param [EventMessage] message
|
|
23
|
+
# @return [undefined]
|
|
24
|
+
def initialize(message)
|
|
25
|
+
@message = message
|
|
26
|
+
@cache = SerializedObjectCache.new message
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @see Message#and_metadata
|
|
30
|
+
# @param [Hash] additional_metadata
|
|
31
|
+
# @return [SerializationAwareEventMessage]
|
|
32
|
+
def and_metadata(additional_metadata)
|
|
33
|
+
new_message = @message.and_metadata additional_metadata
|
|
34
|
+
if new_message.equal? @message
|
|
35
|
+
return self
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
self.class.new new_message
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @see Message#with_metadata
|
|
42
|
+
# @param [Hash] replacement_metadata
|
|
43
|
+
# @return [SerializationAwareEventMessage]
|
|
44
|
+
def with_metadata(replacement_metadata)
|
|
45
|
+
new_message = @message.with_metadata replacement_metadata
|
|
46
|
+
if new_message.equal? @message
|
|
47
|
+
return self
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
self.class.new new_message
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Delegators for the serialized object cache
|
|
54
|
+
def_delegators :@cache, :serialize_metadata, :serialize_payload
|
|
55
|
+
|
|
56
|
+
# Delegators for message attribute readers
|
|
57
|
+
def_delegators :@message, :id, :metadata, :payload, :payload_type, :timestamp
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Decorator for a domain event message that adds serialization awareness
|
|
61
|
+
class SerializationAwareDomainEventMessage < SerializationAwareEventMessage
|
|
62
|
+
# Delegators for domain event specific attribute readers
|
|
63
|
+
def_delegators :@message, :aggregate_id, :sequence_number
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Serialized representation of a message
|
|
4
|
+
class SerializedMessage
|
|
5
|
+
include SerializationAware
|
|
6
|
+
|
|
7
|
+
# @return [String]
|
|
8
|
+
attr_reader :id
|
|
9
|
+
|
|
10
|
+
# @return [LazyObject]
|
|
11
|
+
attr_reader :serialized_metadata
|
|
12
|
+
|
|
13
|
+
# @return [LazyObject]
|
|
14
|
+
attr_reader :serialized_payload
|
|
15
|
+
|
|
16
|
+
# @param [String] id
|
|
17
|
+
# @param [LazyObject] metadata
|
|
18
|
+
# @param [LazyObject] payload
|
|
19
|
+
# @return [undefined]
|
|
20
|
+
def initialize(id, metadata, payload)
|
|
21
|
+
@id = id
|
|
22
|
+
@serialized_metadata = metadata
|
|
23
|
+
@serialized_payload = payload
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @return [Hash] The deserialized metadata for this message
|
|
27
|
+
def metadata
|
|
28
|
+
@serialized_metadata.deserialized
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @return [Object] The deserialized payload for this message
|
|
32
|
+
def payload
|
|
33
|
+
@serialized_payload.deserialized
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @return [Class] The type of payload for this message
|
|
37
|
+
def payload_type
|
|
38
|
+
@serialized_payload.type
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns a copy of this message with the given metadata merged in
|
|
42
|
+
#
|
|
43
|
+
# @see Message#and_metadata
|
|
44
|
+
# @param [Hash] additional_metadata
|
|
45
|
+
# @return [SerializedMessage]
|
|
46
|
+
def and_metadata(additional_metadata)
|
|
47
|
+
if additional_metadata.empty?
|
|
48
|
+
return self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
self.class.build do |builder|
|
|
52
|
+
build_duplicate builder, metadata.merge(additional_metadata)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns a copy of this message with the metadata replaced with the given metadata
|
|
57
|
+
#
|
|
58
|
+
# @see Message#with_metadata
|
|
59
|
+
# @param [Hash] replacement_metadata
|
|
60
|
+
# @return [SerializedMessage]
|
|
61
|
+
def with_metadata(replacement_metadata)
|
|
62
|
+
if @serialized_metadata.deserialized == replacement_metadata
|
|
63
|
+
return self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
self.class.build do |builder|
|
|
67
|
+
build_duplicate builder, replacement_metadata
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @see SerializationAware#serialize_metadata
|
|
72
|
+
# @param [Serializer] serializer
|
|
73
|
+
# @param [Class] expected_type
|
|
74
|
+
# @return [SerializedObject]
|
|
75
|
+
def serialize_metadata(serializer, expected_type)
|
|
76
|
+
serialize @serialized_metadata, serializer, expected_type
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# @see SerializationAware#serialize_payload
|
|
80
|
+
# @param [Serializer] serializer
|
|
81
|
+
# @param [Class] expected_type
|
|
82
|
+
# @return [SerializedObject]
|
|
83
|
+
def serialize_payload(serializer, expected_type)
|
|
84
|
+
serialize @serialized_payload, serializer, expected_type
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Returns the type of builder that can be used to build this type of message
|
|
88
|
+
# @return [Class]
|
|
89
|
+
def self.builder
|
|
90
|
+
SerializedMessageBuilder
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Yields a message builder that can be used to produce a message
|
|
94
|
+
#
|
|
95
|
+
# @see SerializedMessageBuilder#build
|
|
96
|
+
# @yield [SerializedMessageBuilder]
|
|
97
|
+
# @return [SerializedMessage]
|
|
98
|
+
def self.build(&block)
|
|
99
|
+
builder.build(&block)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
protected
|
|
103
|
+
|
|
104
|
+
# Populates a duplicated message with attributes from this message
|
|
105
|
+
#
|
|
106
|
+
# @param [SerializedMessageBuilder] builder
|
|
107
|
+
# @param [Hash] metadata
|
|
108
|
+
# @return [undefined]
|
|
109
|
+
def build_duplicate(builder, metadata)
|
|
110
|
+
builder.id = @id
|
|
111
|
+
builder.metadata = DeserializedObject.new metadata
|
|
112
|
+
builder.payload = @serialized_payload
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
# @param [LazyObject] object
|
|
118
|
+
# @param [Serializer] serializer
|
|
119
|
+
# @param [Class] expected_type
|
|
120
|
+
# @return [SerializedObject]
|
|
121
|
+
def serialize(object, serializer, expected_type)
|
|
122
|
+
if object.serializer.equal? serializer
|
|
123
|
+
serialized = object.serialized_object
|
|
124
|
+
serializer.converter_factory.convert serialized, expected_type
|
|
125
|
+
else
|
|
126
|
+
serializer.serialize object.deserialized, expected_type
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Serialized representation of an event message
|
|
132
|
+
class SerializedEventMessage < SerializedMessage
|
|
133
|
+
# @return [Time]
|
|
134
|
+
attr_reader :timestamp
|
|
135
|
+
|
|
136
|
+
# @param [String] id
|
|
137
|
+
# @param [LazyObject] metadata
|
|
138
|
+
# @param [LazyObject] payload
|
|
139
|
+
# @param [Time] timestamp
|
|
140
|
+
# @return [undefined]
|
|
141
|
+
def initialize(id, metadata, payload, timestamp)
|
|
142
|
+
super id, metadata, payload
|
|
143
|
+
@timestamp = timestamp
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# @return [Class]
|
|
147
|
+
def self.builder
|
|
148
|
+
SerializedEventMessageBuilder
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
protected
|
|
152
|
+
|
|
153
|
+
# @param [SerializedEventMessageBuilder] builder
|
|
154
|
+
# @param [Hash] metadata
|
|
155
|
+
# @return [undefined]
|
|
156
|
+
def build_duplicate(builder, metadata)
|
|
157
|
+
super
|
|
158
|
+
builder.timestamp = @timestamp
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Serialized representation of a domain event message
|
|
163
|
+
class SerializedDomainEventMessage < SerializedEventMessage
|
|
164
|
+
# @return [Object]
|
|
165
|
+
attr_reader :aggregate_id
|
|
166
|
+
|
|
167
|
+
# @return [Integer]
|
|
168
|
+
attr_reader :sequence_number
|
|
169
|
+
|
|
170
|
+
# @param [String] id
|
|
171
|
+
# @param [LazyObject] metadata
|
|
172
|
+
# @param [LazyObject] payload
|
|
173
|
+
# @param [Time] timestamp
|
|
174
|
+
# @param [Object] aggregate_id
|
|
175
|
+
# @param [Integer] sequence_number
|
|
176
|
+
# @return [undefined]
|
|
177
|
+
def initialize(id, metadata, payload, timestamp, aggregate_id, sequence_number)
|
|
178
|
+
super id, metadata, payload, timestamp
|
|
179
|
+
|
|
180
|
+
@aggregate_id = aggregate_id
|
|
181
|
+
@sequence_number = sequence_number
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# @return [Class]
|
|
185
|
+
def self.builder
|
|
186
|
+
SerializedDomainEventMessageBuilder
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
protected
|
|
190
|
+
|
|
191
|
+
# @param [SerializedDomainEventMessageBuilder] builder
|
|
192
|
+
# @param [Hash] metadata
|
|
193
|
+
# @return [undefined]
|
|
194
|
+
def build_duplicate(builder, metadata)
|
|
195
|
+
super
|
|
196
|
+
builder.aggregate_id = @aggregate_id
|
|
197
|
+
builder.sequence_number = @sequence_number
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Message builder capable of producing SerializedMessage instances
|
|
4
|
+
class SerializedMessageBuilder
|
|
5
|
+
# @return [String]
|
|
6
|
+
attr_accessor :id
|
|
7
|
+
|
|
8
|
+
# @return [LazyObject]
|
|
9
|
+
attr_accessor :metadata
|
|
10
|
+
|
|
11
|
+
# @return [LazyObject]
|
|
12
|
+
attr_accessor :payload
|
|
13
|
+
|
|
14
|
+
def self.build
|
|
15
|
+
builder = self.new
|
|
16
|
+
|
|
17
|
+
yield builder if block_given?
|
|
18
|
+
|
|
19
|
+
builder.build
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def build
|
|
23
|
+
SerializedMessage.new @id, @metadata, @payload
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Message builder capable of producing SerializedEventMessage instances
|
|
28
|
+
class SerializedEventMessageBuilder < SerializedMessageBuilder
|
|
29
|
+
# @return [Time]
|
|
30
|
+
attr_accessor :timestamp
|
|
31
|
+
|
|
32
|
+
# @return [SerializedEventMessage]
|
|
33
|
+
def build
|
|
34
|
+
SerializedEventMessage.new @id, @metadata, @payload, @timestamp
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Message builder capable of producing SerializedDomainEventMessage instances
|
|
39
|
+
class SerializedDomainEventMessageBuilder < SerializedEventMessageBuilder
|
|
40
|
+
# @return [Object]
|
|
41
|
+
attr_accessor :aggregate_id
|
|
42
|
+
|
|
43
|
+
# @return [Integer]
|
|
44
|
+
attr_accessor :sequence_number
|
|
45
|
+
|
|
46
|
+
# @param [SerializedDomainEventData] data
|
|
47
|
+
# @param [Serializer] serializer
|
|
48
|
+
# @return [undefined]
|
|
49
|
+
def from_data(data, serializer)
|
|
50
|
+
@id = data.id
|
|
51
|
+
@metadata ||= LazyObject.new data.metadata, serializer
|
|
52
|
+
@payload ||= LazyObject.new data.payload, serializer
|
|
53
|
+
@timestamp = data.timestamp
|
|
54
|
+
@aggregate_id = data.aggregate_id
|
|
55
|
+
@sequence_number = data.sequence_number
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @return [SerializedDomainEventMessage]
|
|
59
|
+
def build
|
|
60
|
+
SerializedDomainEventMessage.new @id, @metadata, @payload, @timestamp, @aggregate_id, @sequence_number
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Thread-safe cache for messages to store serialized metadata and payload
|
|
4
|
+
# @api private
|
|
5
|
+
class SerializedObjectCache
|
|
6
|
+
# @param [Message] message
|
|
7
|
+
# @return [undefined]
|
|
8
|
+
def initialize(message)
|
|
9
|
+
@message = message
|
|
10
|
+
@lock = Mutex.new
|
|
11
|
+
@metadata_cache = Hash.new
|
|
12
|
+
@payload_cache = Hash.new
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @param [Serializer] serializer
|
|
16
|
+
# @param [Class] expected_type
|
|
17
|
+
# @return [SerializedObject]
|
|
18
|
+
def serialize_metadata(serializer, expected_type)
|
|
19
|
+
serialize @message.metadata, @metadata_cache, serializer, expected_type
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @param [Serializer] serializer
|
|
23
|
+
# @param [Class] expected_type
|
|
24
|
+
# @return [SerializedObject]
|
|
25
|
+
def serialize_payload(serializer, expected_type)
|
|
26
|
+
serialize @message.payload, @payload_cache, serializer, expected_type
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# @param [Object] object
|
|
32
|
+
# @param [Hash<Serializer, SerializedObject>] cache
|
|
33
|
+
# @param [Serializer] serializer
|
|
34
|
+
# @param [Class] expected_type
|
|
35
|
+
# @return [SerializedObject]
|
|
36
|
+
def serialize(object, cache, serializer, expected_type)
|
|
37
|
+
@lock.synchronize do
|
|
38
|
+
serialized = cache[serializer]
|
|
39
|
+
if serialized
|
|
40
|
+
serializer.converter_factory.convert serialized, expected_type
|
|
41
|
+
else
|
|
42
|
+
serialized = serializer.serialize object, expected_type
|
|
43
|
+
cache[serializer] = serialized
|
|
44
|
+
serialized
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Synapse
|
|
2
|
+
module Serialization
|
|
3
|
+
# Serializer that provides convenience methods for serializing messages and adds support
|
|
4
|
+
# for optimizing the serialization process
|
|
5
|
+
class MessageSerializer
|
|
6
|
+
extend Forwardable
|
|
7
|
+
|
|
8
|
+
# @param [Serializer] serializer
|
|
9
|
+
# @return [undefined]
|
|
10
|
+
def initialize(serializer)
|
|
11
|
+
@serializer = serializer
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns the serialized metadata for the given message in the expected type, optimizing
|
|
15
|
+
# the serialization, if possible
|
|
16
|
+
#
|
|
17
|
+
# @param [Message] message
|
|
18
|
+
# @param [Class] expected_type
|
|
19
|
+
# @return [SerializedObject]
|
|
20
|
+
def serialize_metadata(message, expected_type)
|
|
21
|
+
if message.is_a? SerializationAware
|
|
22
|
+
message.serialize_metadata @serializer, expected_type
|
|
23
|
+
else
|
|
24
|
+
serialize message.metadata, expected_type
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns the serialized payload for the given message in the expected type, optimizing
|
|
29
|
+
# the serialization, if possible
|
|
30
|
+
#
|
|
31
|
+
# @param [Message] message
|
|
32
|
+
# @param [Class] expected_type
|
|
33
|
+
# @return [SerializedObject]
|
|
34
|
+
def serialize_payload(message, expected_type)
|
|
35
|
+
if message.is_a? SerializationAware
|
|
36
|
+
message.serialize_payload @serializer, expected_type
|
|
37
|
+
else
|
|
38
|
+
serialize message.payload, expected_type
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Delegators for regular serializer methods
|
|
43
|
+
def_delegators :@serializer, :converter_factory, :serialize, :deserialize,
|
|
44
|
+
:can_serialize_to?, :class_for, :type_for
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|