ruby_event_store 2.3.0 → 2.4.0
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.
- checksums.yaml +4 -4
- data/lib/ruby_event_store/batch_enumerator.rb +3 -3
- data/lib/ruby_event_store/broker.rb +5 -4
- data/lib/ruby_event_store/client.rb +47 -45
- data/lib/ruby_event_store/composed_dispatcher.rb +1 -3
- data/lib/ruby_event_store/correlated_commands.rb +4 -15
- data/lib/ruby_event_store/errors.rb +11 -11
- data/lib/ruby_event_store/event.rb +6 -14
- data/lib/ruby_event_store/expected_version.rb +3 -7
- data/lib/ruby_event_store/in_memory_repository.rb +42 -31
- data/lib/ruby_event_store/instrumented_dispatcher.rb +3 -4
- data/lib/ruby_event_store/instrumented_repository.rb +3 -4
- data/lib/ruby_event_store/link_by_metadata.rb +4 -21
- data/lib/ruby_event_store/mappers/default.rb +6 -4
- data/lib/ruby_event_store/mappers/encryption_key.rb +7 -16
- data/lib/ruby_event_store/mappers/encryption_mapper.rb +6 -6
- data/lib/ruby_event_store/mappers/null_mapper.rb +0 -1
- data/lib/ruby_event_store/mappers/pipeline.rb +3 -10
- data/lib/ruby_event_store/mappers/pipeline_mapper.rb +1 -0
- data/lib/ruby_event_store/mappers/transformation/domain_event.rb +21 -21
- data/lib/ruby_event_store/mappers/transformation/encryption.rb +21 -25
- data/lib/ruby_event_store/mappers/transformation/event_class_remapper.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/stringify_metadata_keys.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/symbolize_metadata_keys.rb +6 -5
- data/lib/ruby_event_store/mappers/transformation/upcast.rb +2 -6
- data/lib/ruby_event_store/metadata.rb +43 -14
- data/lib/ruby_event_store/projection.rb +10 -18
- data/lib/ruby_event_store/record.rb +14 -26
- data/lib/ruby_event_store/serialized_record.rb +14 -26
- data/lib/ruby_event_store/serializers/yaml.rb +17 -0
- data/lib/ruby_event_store/spec/broker_lint.rb +27 -17
- data/lib/ruby_event_store/spec/event_lint.rb +1 -1
- data/lib/ruby_event_store/spec/event_repository_lint.rb +513 -556
- data/lib/ruby_event_store/spec/mapper_lint.rb +2 -2
- data/lib/ruby_event_store/spec/subscriptions_lint.rb +23 -22
- data/lib/ruby_event_store/specification.rb +20 -16
- data/lib/ruby_event_store/specification_reader.rb +2 -3
- data/lib/ruby_event_store/specification_result.rb +52 -46
- data/lib/ruby_event_store/stream.rb +3 -7
- data/lib/ruby_event_store/subscriptions.rb +13 -14
- data/lib/ruby_event_store/transform_keys.rb +1 -1
- data/lib/ruby_event_store/version.rb +1 -1
- data/lib/ruby_event_store.rb +1 -0
- metadata +6 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21f9e0f89d5ab86baa4f840b70c2093d518e8077ee8380cce54144c0f123aaf0
|
4
|
+
data.tar.gz: 9927020649c8f492843ce48af29b020e7831efae54a949cb2e8078288254bed9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4763bae7c34f07594ff9757f6482de78c84550bec861210e89930624438025ad0882bb7476eba0f1b511b02b2ff17c63c82a39b9ab065586dfc2704e6b21b6ba
|
7
|
+
data.tar.gz: 7ed29eadf34c3b9c3e22169250dfc5c9da81f2fa6f470c57c39313f79125c14ea57f2fd0a2c30715a915417ae84eb1b69bd8ec06a6b01de94e5bc000bea2f8ba
|
@@ -3,9 +3,9 @@
|
|
3
3
|
module RubyEventStore
|
4
4
|
class BatchEnumerator
|
5
5
|
def initialize(batch_size, total_limit, reader)
|
6
|
-
@batch_size
|
6
|
+
@batch_size = batch_size
|
7
7
|
@total_limit = total_limit
|
8
|
-
@reader
|
8
|
+
@reader = reader
|
9
9
|
end
|
10
10
|
|
11
11
|
def each
|
@@ -13,7 +13,7 @@ module RubyEventStore
|
|
13
13
|
|
14
14
|
0.step(total_limit - 1, batch_size) do |batch_offset|
|
15
15
|
batch_limit = [batch_size, total_limit - batch_offset].min
|
16
|
-
result
|
16
|
+
result = reader.call(batch_offset, batch_limit)
|
17
17
|
|
18
18
|
break if result.empty?
|
19
19
|
yield result
|
@@ -9,9 +9,7 @@ module RubyEventStore
|
|
9
9
|
|
10
10
|
def call(event, record)
|
11
11
|
subscribers = subscriptions.all_for(event.event_type)
|
12
|
-
subscribers.each
|
13
|
-
dispatcher.call(subscriber, event, record)
|
14
|
-
end
|
12
|
+
subscribers.each { |subscriber| dispatcher.call(subscriber, event, record) }
|
15
13
|
end
|
16
14
|
|
17
15
|
def add_subscription(subscriber, event_types)
|
@@ -35,11 +33,14 @@ module RubyEventStore
|
|
35
33
|
end
|
36
34
|
|
37
35
|
private
|
36
|
+
|
38
37
|
attr_reader :dispatcher, :subscriptions
|
39
38
|
|
40
39
|
def verify_subscription(subscriber)
|
41
40
|
raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber
|
42
|
-
|
41
|
+
unless dispatcher.verify(subscriber)
|
42
|
+
raise InvalidHandler.new("Handler #{subscriber} is invalid for dispatcher #{dispatcher}")
|
43
|
+
end
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -4,24 +4,23 @@ require "concurrent"
|
|
4
4
|
|
5
5
|
module RubyEventStore
|
6
6
|
class Client
|
7
|
-
def initialize(
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@repository
|
16
|
-
@mapper
|
17
|
-
@subscriptions
|
18
|
-
@broker
|
19
|
-
@clock
|
20
|
-
@metadata
|
7
|
+
def initialize(
|
8
|
+
repository:,
|
9
|
+
mapper: Mappers::Default.new,
|
10
|
+
subscriptions: Subscriptions.new,
|
11
|
+
dispatcher: Dispatcher.new,
|
12
|
+
clock: default_clock,
|
13
|
+
correlation_id_generator: default_correlation_id_generator
|
14
|
+
)
|
15
|
+
@repository = repository
|
16
|
+
@mapper = mapper
|
17
|
+
@subscriptions = subscriptions
|
18
|
+
@broker = Broker.new(subscriptions: subscriptions, dispatcher: dispatcher)
|
19
|
+
@clock = clock
|
20
|
+
@metadata = Concurrent::ThreadLocalVar.new
|
21
21
|
@correlation_id_generator = correlation_id_generator
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
24
|
# Persists events and notifies subscribed handlers about them
|
26
25
|
#
|
27
26
|
# @param events [Array<Event>, Event] event(s)
|
@@ -30,13 +29,10 @@ module RubyEventStore
|
|
30
29
|
# @return [self]
|
31
30
|
def publish(events, stream_name: GLOBAL_STREAM, expected_version: :any)
|
32
31
|
enriched_events = enrich_events_metadata(events)
|
33
|
-
records
|
32
|
+
records = transform(enriched_events)
|
34
33
|
append_records_to_stream(records, stream_name: stream_name, expected_version: expected_version)
|
35
34
|
enriched_events.zip(records) do |event, record|
|
36
|
-
with_metadata(
|
37
|
-
correlation_id: event.metadata.fetch(:correlation_id),
|
38
|
-
causation_id: event.event_id,
|
39
|
-
) do
|
35
|
+
with_metadata(correlation_id: event.metadata.fetch(:correlation_id), causation_id: event.event_id) do
|
40
36
|
broker.(event, record)
|
41
37
|
end
|
42
38
|
end
|
@@ -121,6 +117,16 @@ module RubyEventStore
|
|
121
117
|
repository.global_position(event_id)
|
122
118
|
end
|
123
119
|
|
120
|
+
# Checks whether event is linked in given stream
|
121
|
+
#
|
122
|
+
# @param event_id [String]
|
123
|
+
# @param stream_name [String]
|
124
|
+
# @return [Boolean] true if event is linked to given stream, false otherwise
|
125
|
+
def event_in_stream?(event_id, stream_name)
|
126
|
+
stream = Stream.new(stream_name)
|
127
|
+
stream.global? ? repository.has_event?(event_id) : repository.event_in_stream?(event_id, stream)
|
128
|
+
end
|
129
|
+
|
124
130
|
# Subscribes a handler (subscriber) that will be invoked for published events of provided type.
|
125
131
|
#
|
126
132
|
# @overload subscribe(subscriber, to:)
|
@@ -170,7 +176,7 @@ module RubyEventStore
|
|
170
176
|
@block = block
|
171
177
|
@broker = broker
|
172
178
|
@global_subscribers = []
|
173
|
-
@subscribers = Hash.new {[]}
|
179
|
+
@subscribers = Hash.new { [] }
|
174
180
|
end
|
175
181
|
|
176
182
|
# Subscribes temporary handlers that
|
@@ -202,7 +208,7 @@ module RubyEventStore
|
|
202
208
|
# @param to [Array<Class>] types of events to subscribe
|
203
209
|
# @param handler [Proc] handler passed as proc
|
204
210
|
# @return [self]
|
205
|
-
def subscribe(handler=nil, to:, &handler2)
|
211
|
+
def subscribe(handler = nil, to:, &handler2)
|
206
212
|
raise ArgumentError if handler && handler2
|
207
213
|
@subscribers[handler || handler2] += Array(to)
|
208
214
|
self
|
@@ -214,7 +220,7 @@ module RubyEventStore
|
|
214
220
|
#
|
215
221
|
# @return [Object] value returned by the invoked block of code
|
216
222
|
def call
|
217
|
-
unsubs
|
223
|
+
unsubs = add_thread_global_subscribers
|
218
224
|
unsubs += add_thread_subscribers
|
219
225
|
@block.call
|
220
226
|
ensure
|
@@ -224,15 +230,11 @@ module RubyEventStore
|
|
224
230
|
private
|
225
231
|
|
226
232
|
def add_thread_subscribers
|
227
|
-
@subscribers.map
|
228
|
-
@broker.add_thread_subscription(subscriber, types)
|
229
|
-
end
|
233
|
+
@subscribers.map { |subscriber, types| @broker.add_thread_subscription(subscriber, types) }
|
230
234
|
end
|
231
235
|
|
232
236
|
def add_thread_global_subscribers
|
233
|
-
@global_subscribers.map
|
234
|
-
@broker.add_thread_global_subscription(subscriber)
|
235
|
-
end
|
237
|
+
@global_subscribers.map { |subscriber| @broker.add_thread_global_subscription(subscriber) }
|
236
238
|
end
|
237
239
|
end
|
238
240
|
|
@@ -265,19 +267,19 @@ module RubyEventStore
|
|
265
267
|
#
|
266
268
|
# @return [Event] deserialized event
|
267
269
|
def deserialize(serializer:, event_type:, event_id:, data:, metadata:, timestamp: nil, valid_at: nil)
|
268
|
-
extract_timestamp = lambda
|
269
|
-
(m[:timestamp] || Time.parse(m.fetch("timestamp"))).iso8601
|
270
|
-
end
|
270
|
+
extract_timestamp = lambda { |m| (m[:timestamp] || Time.parse(m.fetch("timestamp"))).iso8601 }
|
271
271
|
|
272
272
|
mapper.record_to_event(
|
273
|
-
SerializedRecord
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
273
|
+
SerializedRecord
|
274
|
+
.new(
|
275
|
+
event_type: event_type,
|
276
|
+
event_id: event_id,
|
277
|
+
data: data,
|
278
|
+
metadata: metadata,
|
279
|
+
timestamp: timestamp || timestamp_ = extract_timestamp[serializer.load(metadata)],
|
280
|
+
valid_at: valid_at || timestamp_
|
281
|
+
)
|
282
|
+
.deserialize(serializer)
|
281
283
|
)
|
282
284
|
end
|
283
285
|
|
@@ -338,14 +340,14 @@ module RubyEventStore
|
|
338
340
|
|
339
341
|
def enrich_events_metadata(events)
|
340
342
|
events = Array(events)
|
341
|
-
events.each{|event| enrich_event_metadata(event) }
|
343
|
+
events.each { |event| enrich_event_metadata(event) }
|
342
344
|
events
|
343
345
|
end
|
344
346
|
|
345
347
|
def enrich_event_metadata(event)
|
346
348
|
metadata.each { |key, value| event.metadata[key] ||= value }
|
347
|
-
event.metadata[:timestamp]
|
348
|
-
event.metadata[:valid_at]
|
349
|
+
event.metadata[:timestamp] ||= clock.call
|
350
|
+
event.metadata[:valid_at] ||= event.metadata.fetch(:timestamp)
|
349
351
|
event.metadata[:correlation_id] ||= correlation_id_generator.call
|
350
352
|
end
|
351
353
|
|
@@ -364,11 +366,11 @@ module RubyEventStore
|
|
364
366
|
end
|
365
367
|
|
366
368
|
def default_clock
|
367
|
-
->{ Time.now.utc.round(TIMESTAMP_PRECISION) }
|
369
|
+
-> { Time.now.utc.round(TIMESTAMP_PRECISION) }
|
368
370
|
end
|
369
371
|
|
370
372
|
def default_correlation_id_generator
|
371
|
-
->{ SecureRandom.uuid }
|
373
|
+
-> { SecureRandom.uuid }
|
372
374
|
end
|
373
375
|
|
374
376
|
attr_reader :repository, :mapper, :subscriptions, :broker, :clock, :correlation_id_generator
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module RubyEventStore
|
4
4
|
class CorrelatedCommands
|
5
|
-
|
6
5
|
def initialize(event_store, command_bus)
|
7
6
|
@event_store = event_store
|
8
7
|
@command_bus = command_bus
|
@@ -13,23 +12,13 @@ module RubyEventStore
|
|
13
12
|
|
14
13
|
def call(command)
|
15
14
|
correlation_id = event_store.metadata[:correlation_id]
|
16
|
-
causation_id
|
15
|
+
causation_id = event_store.metadata[:causation_id]
|
17
16
|
|
18
17
|
if correlation_id && causation_id
|
19
|
-
command.correlate_with(MiniEvent.new(
|
20
|
-
|
21
|
-
causation_id,
|
22
|
-
)) if command.respond_to?(:correlate_with)
|
23
|
-
event_store.with_metadata(
|
24
|
-
causation_id: command.message_id,
|
25
|
-
) do
|
26
|
-
command_bus.call(command)
|
27
|
-
end
|
18
|
+
command.correlate_with(MiniEvent.new(correlation_id, causation_id)) if command.respond_to?(:correlate_with)
|
19
|
+
event_store.with_metadata(causation_id: command.message_id) { command_bus.call(command) }
|
28
20
|
else
|
29
|
-
event_store.with_metadata(
|
30
|
-
correlation_id: command.message_id,
|
31
|
-
causation_id: command.message_id,
|
32
|
-
) do
|
21
|
+
event_store.with_metadata(correlation_id: command.message_id, causation_id: command.message_id) do
|
33
22
|
command_bus.call(command)
|
34
23
|
end
|
35
24
|
end
|
@@ -1,18 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RubyEventStore
|
4
|
-
Error
|
4
|
+
Error = Class.new(StandardError)
|
5
5
|
WrongExpectedEventVersion = Class.new(Error)
|
6
|
-
InvalidExpectedVersion
|
7
|
-
IncorrectStreamData
|
8
|
-
SubscriberNotExist
|
9
|
-
InvalidPageStart
|
10
|
-
InvalidPageStop
|
11
|
-
InvalidPageSize
|
12
|
-
EventDuplicatedInStream
|
13
|
-
ReservedInternalName
|
14
|
-
InvalidHandler
|
15
|
-
EventNotFoundInStream
|
6
|
+
InvalidExpectedVersion = Class.new(Error)
|
7
|
+
IncorrectStreamData = Class.new(Error)
|
8
|
+
SubscriberNotExist = Class.new(Error)
|
9
|
+
InvalidPageStart = Class.new(Error)
|
10
|
+
InvalidPageStop = Class.new(Error)
|
11
|
+
InvalidPageSize = Class.new(Error)
|
12
|
+
EventDuplicatedInStream = Class.new(Error)
|
13
|
+
ReservedInternalName = Class.new(Error)
|
14
|
+
InvalidHandler = Class.new(Error)
|
15
|
+
EventNotFoundInStream = Class.new(Error)
|
16
16
|
|
17
17
|
class EventNotFound < Error
|
18
18
|
attr_reader :event_id
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require "securerandom"
|
4
4
|
|
5
5
|
module RubyEventStore
|
6
|
-
|
7
6
|
# Data structure representing an event
|
8
7
|
class Event
|
9
8
|
# Instantiates a new event
|
@@ -17,7 +16,7 @@ module RubyEventStore
|
|
17
16
|
def initialize(event_id: SecureRandom.uuid, metadata: nil, data: {})
|
18
17
|
@event_id = event_id.to_s
|
19
18
|
@metadata = Metadata.new(metadata.to_h)
|
20
|
-
@data
|
19
|
+
@data = data
|
21
20
|
end
|
22
21
|
|
23
22
|
attr_reader :event_id, :metadata, :data
|
@@ -59,10 +58,8 @@ module RubyEventStore
|
|
59
58
|
# Event equality ignores metadata!
|
60
59
|
# @return [TrueClass, FalseClass]
|
61
60
|
def ==(other_event)
|
62
|
-
other_event.instance_of?(self.class) &&
|
63
|
-
other_event.
|
64
|
-
other_event.event_id.eql?(event_id) &&
|
65
|
-
other_event.data.eql?(data)
|
61
|
+
other_event.instance_of?(self.class) && other_event.event_type.eql?(event_type) &&
|
62
|
+
other_event.event_id.eql?(event_id) && other_event.data.eql?(data)
|
66
63
|
end
|
67
64
|
|
68
65
|
# @private
|
@@ -80,12 +77,7 @@ module RubyEventStore
|
|
80
77
|
# * data
|
81
78
|
def hash
|
82
79
|
# We don't use metadata because == does not use metadata
|
83
|
-
[
|
84
|
-
self.class,
|
85
|
-
event_type,
|
86
|
-
event_id,
|
87
|
-
data
|
88
|
-
].hash ^ BIG_VALUE
|
80
|
+
[self.class, event_type, event_id, data].hash ^ BIG_VALUE
|
89
81
|
end
|
90
82
|
|
91
83
|
# Reads correlation_id from metadata.
|
@@ -119,7 +111,7 @@ module RubyEventStore
|
|
119
111
|
# @param val [String]
|
120
112
|
# @return [String]
|
121
113
|
def causation_id=(val)
|
122
|
-
metadata[:causation_id]= val
|
114
|
+
metadata[:causation_id] = val
|
123
115
|
end
|
124
116
|
|
125
117
|
# Sets correlation_id and causation_id in metadata based
|
@@ -130,7 +122,7 @@ module RubyEventStore
|
|
130
122
|
# @return [String] set causation_id
|
131
123
|
def correlate_with(other_message)
|
132
124
|
self.correlation_id = other_message.correlation_id || other_message.message_id
|
133
|
-
self.causation_id
|
125
|
+
self.causation_id = other_message.message_id
|
134
126
|
self
|
135
127
|
end
|
136
128
|
|
@@ -21,7 +21,7 @@ module RubyEventStore
|
|
21
21
|
|
22
22
|
def initialize(version)
|
23
23
|
@version = version
|
24
|
-
invalid_version! unless [Integer, :any, :none, :auto].any? {|i| i === version}
|
24
|
+
invalid_version! unless [Integer, :any, :none, :auto].any? { |i| i === version }
|
25
25
|
end
|
26
26
|
|
27
27
|
def any?
|
@@ -53,15 +53,11 @@ module RubyEventStore
|
|
53
53
|
private_constant :BIG_VALUE
|
54
54
|
|
55
55
|
def hash
|
56
|
-
[
|
57
|
-
self.class,
|
58
|
-
version
|
59
|
-
].hash ^ BIG_VALUE
|
56
|
+
[self.class, version].hash ^ BIG_VALUE
|
60
57
|
end
|
61
58
|
|
62
59
|
def ==(other_expected_version)
|
63
|
-
other_expected_version.instance_of?(self.class) &&
|
64
|
-
other_expected_version.version.equal?(version)
|
60
|
+
other_expected_version.instance_of?(self.class) && other_expected_version.version.equal?(version)
|
65
61
|
end
|
66
62
|
|
67
63
|
alias_method :eql?, :==
|
@@ -26,7 +26,7 @@ module RubyEventStore
|
|
26
26
|
def initialize(serializer: NULL, ensure_supported_any_usage: false)
|
27
27
|
@serializer = serializer
|
28
28
|
@streams = Hash.new { |h, k| h[k] = Array.new }
|
29
|
-
@mutex
|
29
|
+
@mutex = Mutex.new
|
30
30
|
@storage = Hash.new
|
31
31
|
@ensure_supported_any_usage = ensure_supported_any_usage
|
32
32
|
end
|
@@ -36,7 +36,9 @@ module RubyEventStore
|
|
36
36
|
|
37
37
|
with_synchronize(expected_version, stream) do |resolved_version|
|
38
38
|
ensure_supported_any_usage(resolved_version, stream)
|
39
|
-
|
39
|
+
unless resolved_version.nil? || last_stream_version(stream).equal?(resolved_version)
|
40
|
+
raise WrongExpectedEventVersion
|
41
|
+
end
|
40
42
|
|
41
43
|
serialized_records.each_with_index do |serialized_record, index|
|
42
44
|
raise EventDuplicatedInStream if has_event?(serialized_record.event_id)
|
@@ -52,7 +54,9 @@ module RubyEventStore
|
|
52
54
|
|
53
55
|
with_synchronize(expected_version, stream) do |resolved_version|
|
54
56
|
ensure_supported_any_usage(resolved_version, stream)
|
55
|
-
|
57
|
+
unless resolved_version.nil? || last_stream_version(stream).equal?(resolved_version)
|
58
|
+
raise WrongExpectedEventVersion
|
59
|
+
end
|
56
60
|
|
57
61
|
serialized_records.each_with_index do |serialized_record, index|
|
58
62
|
raise EventDuplicatedInStream if has_event_in_stream?(serialized_record.event_id, stream.name)
|
@@ -91,9 +95,7 @@ module RubyEventStore
|
|
91
95
|
serialized_records.last&.deserialize(serializer)
|
92
96
|
else
|
93
97
|
Enumerator.new do |y|
|
94
|
-
serialized_records.each
|
95
|
-
y << serialized_record.deserialize(serializer)
|
96
|
-
end
|
98
|
+
serialized_records.each { |serialized_record| y << serialized_record.deserialize(serializer) }
|
97
99
|
end
|
98
100
|
end
|
99
101
|
end
|
@@ -106,26 +108,26 @@ module RubyEventStore
|
|
106
108
|
records.each do |record|
|
107
109
|
read_event(record.event_id)
|
108
110
|
serialized_record =
|
109
|
-
Record
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
111
|
+
Record
|
112
|
+
.new(
|
113
|
+
event_id: record.event_id,
|
114
|
+
event_type: record.event_type,
|
115
|
+
data: record.data,
|
116
|
+
metadata: record.metadata,
|
117
|
+
timestamp: Time.iso8601(storage.fetch(record.event_id).timestamp),
|
118
|
+
valid_at: record.valid_at
|
119
|
+
)
|
120
|
+
.serialize(serializer)
|
117
121
|
storage[record.event_id] = serialized_record
|
118
122
|
end
|
119
123
|
end
|
120
124
|
|
121
125
|
def streams_of(event_id)
|
122
|
-
streams
|
123
|
-
.select { |name,| has_event_in_stream?(event_id, name) }
|
124
|
-
.map { |name,| Stream.new(name) }
|
126
|
+
streams.select { |name,| has_event_in_stream?(event_id, name) }.map { |name,| Stream.new(name) }
|
125
127
|
end
|
126
128
|
|
127
129
|
def position_in_stream(event_id, stream)
|
128
|
-
event_in_stream = streams[stream.name].find {|event_in_stream| event_in_stream.event_id.eql?(event_id) }
|
130
|
+
event_in_stream = streams[stream.name].find { |event_in_stream| event_in_stream.event_id.eql?(event_id) }
|
129
131
|
raise EventNotFoundInStream if event_in_stream.nil?
|
130
132
|
event_in_stream.position
|
131
133
|
end
|
@@ -134,20 +136,33 @@ module RubyEventStore
|
|
134
136
|
storage.keys.index(event_id) or raise EventNotFound.new(event_id)
|
135
137
|
end
|
136
138
|
|
139
|
+
def event_in_stream?(event_id, stream)
|
140
|
+
!streams[stream.name].find { |event_in_stream| event_in_stream.event_id.eql?(event_id) }.nil?
|
141
|
+
end
|
142
|
+
|
137
143
|
private
|
144
|
+
|
138
145
|
def read_scope(spec)
|
139
146
|
serialized_records = serialized_records_of_stream(spec.stream)
|
140
147
|
serialized_records = ordered(serialized_records, spec)
|
141
|
-
serialized_records = serialized_records.select{|e| spec.with_ids.any?{|x| x.eql?(e.event_id)}} if spec
|
142
|
-
|
148
|
+
serialized_records = serialized_records.select { |e| spec.with_ids.any? { |x| x.eql?(e.event_id) } } if spec
|
149
|
+
.with_ids?
|
150
|
+
serialized_records = serialized_records.select { |e| spec.with_types.any? { |x| x.eql?(e.event_type) } } if spec
|
151
|
+
.with_types?
|
143
152
|
serialized_records = serialized_records.reverse if spec.backward?
|
144
153
|
serialized_records = serialized_records.drop(index_of(serialized_records, spec.start) + 1) if spec.start
|
145
154
|
serialized_records = serialized_records.take(index_of(serialized_records, spec.stop)) if spec.stop
|
146
155
|
serialized_records = serialized_records.take(spec.limit) if spec.limit?
|
147
|
-
serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) < spec.older_than } if spec
|
148
|
-
|
149
|
-
serialized_records =
|
150
|
-
|
156
|
+
serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) < spec.older_than } if spec
|
157
|
+
.older_than
|
158
|
+
serialized_records =
|
159
|
+
serialized_records.select { |sr| Time.iso8601(sr.timestamp) <= spec.older_than_or_equal } if spec
|
160
|
+
.older_than_or_equal
|
161
|
+
serialized_records = serialized_records.select { |sr| Time.iso8601(sr.timestamp) > spec.newer_than } if spec
|
162
|
+
.newer_than
|
163
|
+
serialized_records =
|
164
|
+
serialized_records.select { |sr| Time.iso8601(sr.timestamp) >= spec.newer_than_or_equal } if spec
|
165
|
+
.newer_than_or_equal
|
151
166
|
serialized_records
|
152
167
|
end
|
153
168
|
|
@@ -189,9 +204,7 @@ module RubyEventStore
|
|
189
204
|
# conditions more likely. And we only use mutex.synchronize for writing
|
190
205
|
# not for the whole read+write algorithm.
|
191
206
|
Thread.pass
|
192
|
-
mutex.synchronize
|
193
|
-
block.call(resolved_version)
|
194
|
-
end
|
207
|
+
mutex.synchronize { block.call(resolved_version) }
|
195
208
|
end
|
196
209
|
|
197
210
|
def has_event_in_stream?(event_id, stream_name)
|
@@ -199,13 +212,11 @@ module RubyEventStore
|
|
199
212
|
end
|
200
213
|
|
201
214
|
def index_of(source, event_id)
|
202
|
-
source.index {|item| item.event_id.eql?(event_id)}
|
215
|
+
source.index { |item| item.event_id.eql?(event_id) }
|
203
216
|
end
|
204
217
|
|
205
218
|
def compute_position(resolved_version, index)
|
206
|
-
unless resolved_version.nil?
|
207
|
-
resolved_version + index + 1
|
208
|
-
end
|
219
|
+
resolved_version + index + 1 unless resolved_version.nil?
|
209
220
|
end
|
210
221
|
|
211
222
|
def add_to_stream(stream, serialized_record, resolved_version, index)
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "ruby2_keywords"
|
4
|
-
|
5
3
|
module RubyEventStore
|
6
4
|
class InstrumentedDispatcher
|
7
5
|
def initialize(dispatcher, instrumentation)
|
@@ -15,9 +13,9 @@ module RubyEventStore
|
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
18
|
-
|
16
|
+
def method_missing(method_name, *arguments, **keyword_arguments, &block)
|
19
17
|
if respond_to?(method_name)
|
20
|
-
dispatcher.public_send(method_name, *arguments, &block)
|
18
|
+
dispatcher.public_send(method_name, *arguments, **keyword_arguments, &block)
|
21
19
|
else
|
22
20
|
super
|
23
21
|
end
|
@@ -28,6 +26,7 @@ module RubyEventStore
|
|
28
26
|
end
|
29
27
|
|
30
28
|
private
|
29
|
+
|
31
30
|
attr_reader :instrumentation, :dispatcher
|
32
31
|
end
|
33
32
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "ruby2_keywords"
|
4
|
-
|
5
3
|
module RubyEventStore
|
6
4
|
class InstrumentedRepository
|
7
5
|
def initialize(repository, instrumentation)
|
@@ -51,9 +49,9 @@ module RubyEventStore
|
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
54
|
-
|
52
|
+
def method_missing(method_name, *arguments, **keyword_arguments, &block)
|
55
53
|
if respond_to?(method_name)
|
56
|
-
repository.public_send(method_name, *arguments, &block)
|
54
|
+
repository.public_send(method_name, *arguments, **keyword_arguments, &block)
|
57
55
|
else
|
58
56
|
super
|
59
57
|
end
|
@@ -64,6 +62,7 @@ module RubyEventStore
|
|
64
62
|
end
|
65
63
|
|
66
64
|
private
|
65
|
+
|
67
66
|
attr_reader :repository, :instrumentation
|
68
67
|
end
|
69
68
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
module RubyEventStore
|
4
4
|
class LinkByMetadata
|
5
|
-
|
6
5
|
def initialize(event_store:, key:, prefix: nil)
|
7
6
|
@event_store = event_store
|
8
7
|
@key = key
|
@@ -12,31 +11,19 @@ module RubyEventStore
|
|
12
11
|
def call(event)
|
13
12
|
return unless event.metadata.has_key?(@key)
|
14
13
|
|
15
|
-
@event_store.link(
|
16
|
-
[event.event_id],
|
17
|
-
stream_name: "#{@prefix}#{event.metadata.fetch(@key)}"
|
18
|
-
)
|
14
|
+
@event_store.link([event.event_id], stream_name: "#{@prefix}#{event.metadata.fetch(@key)}")
|
19
15
|
end
|
20
|
-
|
21
16
|
end
|
22
17
|
|
23
18
|
class LinkByCorrelationId < LinkByMetadata
|
24
19
|
def initialize(event_store:, prefix: nil)
|
25
|
-
super(
|
26
|
-
event_store: event_store,
|
27
|
-
prefix: prefix,
|
28
|
-
key: :correlation_id,
|
29
|
-
)
|
20
|
+
super(event_store: event_store, prefix: prefix, key: :correlation_id)
|
30
21
|
end
|
31
22
|
end
|
32
23
|
|
33
24
|
class LinkByCausationId < LinkByMetadata
|
34
25
|
def initialize(event_store:, prefix: nil)
|
35
|
-
super(
|
36
|
-
event_store: event_store,
|
37
|
-
prefix: prefix,
|
38
|
-
key: :causation_id,
|
39
|
-
)
|
26
|
+
super(event_store: event_store, prefix: prefix, key: :causation_id)
|
40
27
|
end
|
41
28
|
end
|
42
29
|
|
@@ -47,11 +34,7 @@ module RubyEventStore
|
|
47
34
|
end
|
48
35
|
|
49
36
|
def call(event)
|
50
|
-
@event_store.link(
|
51
|
-
[event.event_id],
|
52
|
-
stream_name: "#{@prefix}#{event.event_type}"
|
53
|
-
)
|
37
|
+
@event_store.link([event.event_id], stream_name: "#{@prefix}#{event.event_type}")
|
54
38
|
end
|
55
39
|
end
|
56
|
-
|
57
40
|
end
|