ruby_event_store 0.31.1 → 0.32.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: adebf7df2d0a0bec7857885c1e080e92000adcce6e802b2c7162c0e7b4e0ed8a
4
- data.tar.gz: cd37b31c70dcd4646ce59a70a7956f38664792777fca133d08a992deeef43e91
3
+ metadata.gz: bab926d223e59f80a3c302a45cc70f6cfd4d82e5f768294701ca5474c63c03bd
4
+ data.tar.gz: 8856dbe54742b11daa510d45b9d6b7dd48d19b82593796786c9a4a859b852655
5
5
  SHA512:
6
- metadata.gz: 04f7de987acc0e3d52ddd8dc70c158f46967aece05ddf8f109bc5fe395ede108c1e402cbc98b089f6adcbd48219a076f7b678a9106657807a4a8d4eeba2de9b7
7
- data.tar.gz: c2c1eb24d23f2f5d98b7b44e06e90f0901fe99b108adf3865de81af41bc161b4253e188c370bcd27cb1cf61bdb732bf6ba7f224f1436375bb885a5c9ec8bea95
6
+ metadata.gz: 528ba2456e22858c87dea1cea275fd97a63404080c2b7143248ccec3b43c2be45781fe20caf3460afb8d01e900cc5db40c99962686d66a84d40c66cee694288f
7
+ data.tar.gz: 65100e90a4ed432b7ded41bca6f15d30a4acd60b21bdea373ad191900f8f98bb610605481fd4b3f3d9b1bf19718a527114f8f6582b941d4a7f48286fe8f41ec3
data/Gemfile CHANGED
@@ -1,3 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
- gem 'protobuf_nested_struct'
3
+
4
+ gem 'protobuf_nested_struct'
data/Makefile CHANGED
@@ -1,25 +1,25 @@
1
1
  GEM_VERSION = $(shell cat ../RES_VERSION)
2
2
  GEM_NAME = ruby_event_store
3
3
  REQUIRE = $(GEM_NAME)
4
- IGNORE = RubyEventStore.const_missing \
5
- RubyEventStore::InMemoryRepository\#append_with_synchronize \
4
+ IGNORE = RubyEventStore::InMemoryRepository\#append_with_synchronize \
6
5
  RubyEventStore::InMemoryRepository\#normalize_to_array \
7
6
  RubyEventStore::Client\#normalize_to_array \
8
7
  RubyEventStore::Client::Within\#normalize_to_array \
9
8
  RubyEventStore::Client::Within\#add_thread_subscribers \
10
9
  RubyEventStore::Client::Within\#add_thread_global_subscribers \
11
- RubyEventStore::Client\#read_all_streams_forward \
12
- RubyEventStore::Client\#read_all_streams_backward \
13
- RubyEventStore::Client\#read_stream_events_forward \
14
- RubyEventStore::Client\#read_stream_events_backward \
15
- RubyEventStore::Client\#read_events_forward \
16
- RubyEventStore::Client\#read_events_backward \
17
10
  RubyEventStore::DeprecatedReadAPIRunner* \
18
11
  RubyEventStore::DeprecatedReadAPIRewriter* \
19
12
  RubyEventStore::Client\#publish_event \
20
13
  RubyEventStore::Client\#publish_events \
21
14
  RubyEventStore::Client\#link_to_stream \
22
15
  RubyEventStore::Client\#append_to_stream \
16
+ RubyEventStore::AsyncDispatcher* \
17
+ RubyEventStore::AsyncProxyStrategy::Inline* \
18
+ RubyEventStore::SpecificationResult\#count \
19
+ RubyEventStore::SpecificationResult\#direction \
20
+ RubyEventStore::SpecificationResult\#stream_name \
21
+ RubyEventStore::SpecificationResult\#global_stream? \
22
+
23
23
 
24
24
  SUBJECT ?= RubyEventStore*
25
25
 
@@ -8,10 +8,11 @@ require 'ruby_event_store/constants'
8
8
  require 'ruby_event_store/client'
9
9
  require 'ruby_event_store/metadata'
10
10
  require 'ruby_event_store/specification'
11
+ require 'ruby_event_store/specification_result'
12
+ require 'ruby_event_store/specification_reader'
11
13
  require 'ruby_event_store/event'
12
14
  require 'ruby_event_store/stream'
13
15
  require 'ruby_event_store/expected_version'
14
- require 'ruby_event_store/deprecations'
15
16
  require 'ruby_event_store/serialized_record'
16
17
  require 'ruby_event_store/mappers/default'
17
18
  require 'ruby_event_store/mappers/protobuf'
@@ -21,4 +22,8 @@ require 'ruby_event_store/correlated_commands'
21
22
  require 'ruby_event_store/link_by_metadata'
22
23
  require 'ruby_event_store/async_proxy_strategy'
23
24
  require 'ruby_event_store/async_dispatcher'
25
+ require 'ruby_event_store/immediate_async_dispatcher'
26
+ require 'ruby_event_store/composed_dispatcher'
24
27
  require 'ruby_event_store/version'
28
+ require 'ruby_event_store/instrumented_repository'
29
+ require 'ruby_event_store/instrumented_dispatcher'
@@ -1,8 +1,14 @@
1
1
  module RubyEventStore
2
+ # @deprecated Use RubyEventStore::ImmediateAsyncDispatcher instead
2
3
  class AsyncDispatcher < PubSub::Dispatcher
3
4
  def initialize(proxy_strategy: AsyncProxyStrategy::Inline.new, scheduler:)
4
5
  @async_proxy_strategy = proxy_strategy
5
6
  @scheduler = scheduler
7
+ warn <<~EOW
8
+ RubyEventStore::AsyncDispatcher has been deprecated.
9
+
10
+ Use RubyEventStore::ImmediateAsyncDispatcher instead
11
+ EOW
6
12
  end
7
13
 
8
14
  def call(subscriber, _, serialized_event)
@@ -14,7 +20,7 @@ module RubyEventStore
14
20
  end
15
21
 
16
22
  def verify(subscriber)
17
- super unless @scheduler.async_handler?(subscriber)
23
+ @scheduler.async_handler?(subscriber) || super
18
24
  end
19
25
  end
20
26
  end
@@ -1,6 +1,15 @@
1
1
  module RubyEventStore
2
2
  module AsyncProxyStrategy
3
+ # @deprecated Use RubyEventStore::ImmediateAsyncDispatcher instead
3
4
  class Inline
5
+ def initialize
6
+ warn <<~EOW
7
+ RubyEventStore::AsyncProxyStrategy::Inline has been deprecated.
8
+
9
+ Use RubyEventStore::ImmediateAsyncDispatcher instead
10
+ EOW
11
+ end
12
+
4
13
  def call(schedule_proc)
5
14
  schedule_proc.call
6
15
  end
@@ -7,12 +7,10 @@ module RubyEventStore
7
7
  mapper: Mappers::Default.new,
8
8
  subscriptions: PubSub::Subscriptions.new,
9
9
  dispatcher: PubSub::Dispatcher.new,
10
- page_size: PAGE_SIZE,
11
10
  clock: ->{ Time.now.utc })
12
11
  @repository = repository
13
12
  @mapper = mapper
14
13
  @broker = PubSub::Broker.new(subscriptions: subscriptions, dispatcher: dispatcher)
15
- @page_size = page_size
16
14
  @clock = clock
17
15
  @metadata = Concurrent::ThreadLocalVar.new
18
16
  end
@@ -23,7 +21,7 @@ module RubyEventStore
23
21
  # @param events [Array<Event, Proto>, Event, Proto] event(s)
24
22
  # @param stream_name [String] name of the stream for persisting events.
25
23
  # @param expected_version [:any, :auto, :none, Integer] controls optimistic locking strategy. {http://railseventstore.org/docs/expected_version/ Read more}
26
- # @return [:ok]
24
+ # @return [self]
27
25
  def publish(events, stream_name: GLOBAL_STREAM, expected_version: :any)
28
26
  enriched_events = enrich_events_metadata(events)
29
27
  serialized_events = serialize_events(enriched_events)
@@ -36,7 +34,7 @@ module RubyEventStore
36
34
  broker.(event, serialized_event)
37
35
  end
38
36
  end
39
- :ok
37
+ self
40
38
  end
41
39
 
42
40
  # @deprecated Use {#publish} instead
@@ -72,11 +70,11 @@ module RubyEventStore
72
70
  # Persists new event(s) without notifying any subscribed handlers
73
71
  #
74
72
  # @param (see #publish)
75
- # @return [:ok]
73
+ # @return [self]
76
74
  def append(events, stream_name: GLOBAL_STREAM, expected_version: :any)
77
75
  serialized_events = serialize_events(enrich_events_metadata(events))
78
76
  append_to_stream_serialized_events(serialized_events, stream_name: stream_name, expected_version: expected_version)
79
- :ok
77
+ self
80
78
  end
81
79
 
82
80
  # Links already persisted event(s) to a different stream.
@@ -106,76 +104,10 @@ module RubyEventStore
106
104
  # longer linked to the stream.
107
105
  #
108
106
  # @param stream_name [String] name of the stream to be cleared.
109
- # @return [:ok]
107
+ # @return [self]
110
108
  def delete_stream(stream_name)
111
109
  repository.delete_stream(Stream.new(stream_name))
112
- :ok
113
- end
114
-
115
- # @deprecated Use {#read} instead. {https://github.com/RailsEventStore/rails_event_store/releases/tag/v0.30.0 More info}
116
- def read_events_forward(stream_name, start: :head, count: page_size)
117
- warn <<~EOW
118
- RubyEventStore::Client#read_events_forward has been deprecated.
119
-
120
- Use following fluent API to receive exact results:
121
- client.read.stream(stream_name).limit(count).from(start).each.to_a
122
- EOW
123
- read.stream(stream_name).limit(count).from(start).each.to_a
124
- end
125
-
126
- # @deprecated Use {#read} instead. {https://github.com/RailsEventStore/rails_event_store/releases/tag/v0.30.0 More info}
127
- def read_events_backward(stream_name, start: :head, count: page_size)
128
- warn <<~EOW
129
- RubyEventStore::Client#read_events_backward has been deprecated.
130
-
131
- Use following fluent API to receive exact results:
132
- client.read.stream(stream_name).limit(count).from(start).backward.each.to_a
133
- EOW
134
- read.stream(stream_name).limit(count).from(start).backward.each.to_a
135
- end
136
-
137
- # @deprecated Use {#read} instead. {https://github.com/RailsEventStore/rails_event_store/releases/tag/v0.30.0 More info}
138
- def read_stream_events_forward(stream_name)
139
- warn <<~EOW
140
- RubyEventStore::Client#read_stream_events_forward has been deprecated.
141
-
142
- Use following fluent API to receive exact results:
143
- client.read.stream(stream_name).each.to_a
144
- EOW
145
- read.stream(stream_name).each.to_a
146
- end
147
-
148
- # @deprecated Use {#read} instead. {https://github.com/RailsEventStore/rails_event_store/releases/tag/v0.30.0 More info}
149
- def read_stream_events_backward(stream_name)
150
- warn <<~EOW
151
- RubyEventStore::Client#read_stream_events_backward has been deprecated.
152
-
153
- Use following fluent API to receive exact results:
154
- client.read.stream(stream_name).backward.each.to_a
155
- EOW
156
- read.stream(stream_name).backward.each.to_a
157
- end
158
-
159
- # @deprecated Use {#read} instead. {https://github.com/RailsEventStore/rails_event_store/releases/tag/v0.30.0 More info}
160
- def read_all_streams_forward(start: :head, count: page_size)
161
- warn <<~EOW
162
- RubyEventStore::Client#read_all_streams_forward has been deprecated.
163
-
164
- Use following fluent API to receive exact results:
165
- client.read.limit(count).from(start).each.to_a
166
- EOW
167
- read.limit(count).from(start).each.to_a
168
- end
169
-
170
- # @deprecated Use {#read} instead. {https://github.com/RailsEventStore/rails_event_store/releases/tag/v0.30.0 More info}
171
- def read_all_streams_backward(start: :head, count: page_size)
172
- warn <<~EOW
173
- RubyEventStore::Client#read_all_streams_backward has been deprecated.
174
-
175
- Use following fluent API to receive exact results:
176
- client.read.limit(count).from(start).backward.each.to_a
177
- EOW
178
- read.limit(count).from(start).backward.each.to_a
110
+ self
179
111
  end
180
112
 
181
113
  # Returns a single, persisted event based on its ID.
@@ -191,7 +123,14 @@ module RubyEventStore
191
123
  #
192
124
  # @return [Specification]
193
125
  def read
194
- Specification.new(repository, mapper)
126
+ Specification.new(SpecificationReader.new(repository, mapper))
127
+ end
128
+
129
+ # Gets list of streams where event is stored or linked
130
+ #
131
+ # @return [Array<Stream>] where event is stored or linked
132
+ def streams_of(event_id)
133
+ repository.streams_of(event_id)
195
134
  end
196
135
 
197
136
  # Subscribes a handler (subscriber) that will be invoked for published events of provided type.
@@ -345,6 +284,42 @@ module RubyEventStore
345
284
  @metadata.value || EMPTY_HASH
346
285
  end
347
286
 
287
+ # Overwrite existing event(s) with the same ID.
288
+ #
289
+ # Does not notify any subscribed handlers.
290
+ # Does not enrich with additional current metadata.
291
+ # Does not allow changing which streams these events are in.
292
+ # {http://railseventstore.org/docs/migrating_messages Read more}
293
+ #
294
+ # @example Add data and metadata to existing events
295
+ #
296
+ # events = event_store.read.limit(10).each.to_a
297
+ # events.each do |ev|
298
+ # ev.data[:tenant_id] = 1
299
+ # ev.metadata[:server_id] = "eu-west-2"
300
+ # end
301
+ # event_store.overwrite(events)
302
+ #
303
+ # @example Change event type
304
+ #
305
+ # events = event_store.read.limit(10).each.select{|ev| OldType === ev }.map do |ev|
306
+ # NewType.new(
307
+ # event_id: ev.event_id,
308
+ # data: ev.data,
309
+ # metadata: ev.metadata,
310
+ # )
311
+ # end
312
+ # event_store.overwrite(events)
313
+ #
314
+ # @param events [Array<Event, Proto>, Event, Proto] event(s) to serialize and overwrite again
315
+ # @return [self]
316
+ def overwrite(events_or_event)
317
+ events = normalize_to_array(events_or_event)
318
+ serialized_events = serialize_events(events)
319
+ repository.update_messages(serialized_events)
320
+ self
321
+ end
322
+
348
323
  EMPTY_HASH = {}.freeze
349
324
  private_constant :EMPTY_HASH
350
325
 
@@ -385,6 +360,6 @@ module RubyEventStore
385
360
  @metadata.value = value
386
361
  end
387
362
 
388
- attr_reader :repository, :mapper, :broker, :clock, :page_size
363
+ attr_reader :repository, :mapper, :broker, :clock
389
364
  end
390
365
  end
@@ -0,0 +1,22 @@
1
+ module RubyEventStore
2
+ class ComposedDispatcher
3
+ def initialize(*dispatchers)
4
+ @dispatchers = dispatchers
5
+ end
6
+
7
+ def call(subscriber, event, serialized_event)
8
+ @dispatchers.each do |dispatcher|
9
+ if dispatcher.verify(subscriber)
10
+ dispatcher.call(subscriber, event, serialized_event)
11
+ break
12
+ end
13
+ end
14
+ end
15
+
16
+ def verify(subscriber)
17
+ @dispatchers.any? do |dispatcher|
18
+ dispatcher.verify(subscriber)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -4,11 +4,22 @@ require 'ruby_event_store'
4
4
 
5
5
 
6
6
  module RubyEventStore
7
- class DeprecatedReadAPIRewriter < ::Parser::Rewriter
7
+ class DeprecatedReadAPIRewriter < ::Parser::TreeRewriter
8
+ DEPRECATED_READER_METHODS = [
9
+ :read_all_streams_backward,
10
+ :read_events_backward,
11
+ :read_stream_events_backward,
12
+ :read_all_streams_forward,
13
+ :read_events_forward,
14
+ :read_stream_events_forward
15
+ ]
16
+ private_constant :DEPRECATED_READER_METHODS
17
+
8
18
  def on_send(node)
9
19
  node.each_descendant(:send) { |desc_node| on_send(desc_node) }
10
20
 
11
21
  _, method_name, *args = node.children
22
+ return unless DEPRECATED_READER_METHODS.include?(method_name)
12
23
  replace_range = node.location.selector
13
24
  replace_range = replace_range.join(node.location.end) if node.location.end
14
25
 
@@ -64,4 +75,4 @@ module RubyEventStore
64
75
  node.children[0].to_sym
65
76
  end
66
77
  end
67
- end
78
+ end
@@ -8,6 +8,7 @@ module RubyEventStore
8
8
  EventDuplicatedInStream = Class.new(StandardError)
9
9
  NotSupported = Class.new(StandardError)
10
10
  ReservedInternalName = Class.new(StandardError)
11
+ InvalidHandler = Class.new(StandardError)
11
12
 
12
13
  class EventNotFound < StandardError
13
14
  attr_reader :event_id
@@ -16,10 +17,4 @@ module RubyEventStore
16
17
  @event_id = event_id
17
18
  end
18
19
  end
19
-
20
- class InvalidHandler < StandardError
21
- def initialize(object)
22
- super("#call method not found in #{object.inspect} subscriber. Are you sure it is a valid subscriber?")
23
- end
24
- end
25
20
  end
@@ -0,0 +1,15 @@
1
+ module RubyEventStore
2
+ class ImmediateAsyncDispatcher
3
+ def initialize(scheduler:)
4
+ @scheduler = scheduler
5
+ end
6
+
7
+ def call(subscriber, _, serialized_event)
8
+ @scheduler.call(subscriber, serialized_event)
9
+ end
10
+
11
+ def verify(subscriber)
12
+ @scheduler.verify(subscriber)
13
+ end
14
+ end
15
+ end
@@ -36,18 +36,39 @@ module RubyEventStore
36
36
  end
37
37
 
38
38
  def read(spec)
39
- events = spec.global_stream? ? global : stream_of(spec.stream_name)
39
+ events = spec.stream.global? ? global : stream_of(spec.stream.name)
40
40
  events = events.reverse if spec.backward?
41
41
  events = events.drop(index_of(events, spec.start) + 1) unless spec.head?
42
- events = events[0...spec.count] if spec.limit?
42
+ events = events[0...spec.limit] if spec.limit?
43
43
  if spec.batched?
44
44
  batch_reader = ->(offset, limit) { events.drop(offset).take(limit) }
45
45
  BatchEnumerator.new(spec.batch_size, events.size, batch_reader).each
46
+ elsif spec.first?
47
+ events.first
48
+ elsif spec.last?
49
+ events.last
46
50
  else
47
51
  events.each
48
52
  end
49
53
  end
50
54
 
55
+ def update_messages(messages)
56
+ messages.each do |new_msg|
57
+ location = global.index{|m| new_msg.event_id.eql?(m.event_id)} or raise EventNotFound.new(new_msg.event_id)
58
+ global[location] = new_msg
59
+ streams.values.each do |str|
60
+ location = str.index{|m| new_msg.event_id.eql?(m.event_id)}
61
+ str[location] = new_msg if location
62
+ end
63
+ end
64
+ end
65
+
66
+ def streams_of(event_id)
67
+ streams.select do |_, stream_events|
68
+ stream_events.any? { |event| event.event_id.equal?(event_id) }
69
+ end.map { |name, _| Stream.new(name) }
70
+ end
71
+
51
72
  private
52
73
 
53
74
  def stream_of(name)
@@ -0,0 +1,21 @@
1
+ module RubyEventStore
2
+ class InstrumentedDispatcher
3
+ def initialize(dispatcher, instrumentation)
4
+ @dispatcher = dispatcher
5
+ @instrumentation = instrumentation
6
+ end
7
+
8
+ def call(subscriber, event, serialized_event)
9
+ instrumentation.instrument("call.dispatcher.rails_event_store", event: event, subscriber: subscriber) do
10
+ dispatcher.call(subscriber, event, serialized_event)
11
+ end
12
+ end
13
+
14
+ def verify(subscriber)
15
+ dispatcher.verify(subscriber)
16
+ end
17
+
18
+ private
19
+ attr_reader :instrumentation, :dispatcher
20
+ end
21
+ end