ruby_event_store 0.29.0 → 0.30.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dce5f67de62e85755060ade796d9f07674197175c867ea6028dca2b9fd730791
4
- data.tar.gz: 95fb9ef4100c3fd2179cb0c5ff7e77e9c31801c68cc5872eb020433e448d1668
3
+ metadata.gz: 4df1be4d7e983bb77d1c069496cdca690f72d593a0c0d83f9d3d7519d63ed115
4
+ data.tar.gz: 0d156019cb436a9fb262b680e3e46d007d7c64ec46f1186bae82c5e4344b03c8
5
5
  SHA512:
6
- metadata.gz: eee87e104fc965fe7c4e7768ba97424d072d816c107d7ed70a8317c86e6b848f532808626851cd3acd9e7ef5f7f3a4fcfa224baa47b631b97b6be6968e82c92c
7
- data.tar.gz: 4aa91e0bf722675f60dff89fcf1b42ab47faf82e95ab4087017f3538b2ea919c814aa63692d467eab69f12ece43efd516bd73ae5c7a3da51af6bfad2f5bbbc60
6
+ metadata.gz: 490e25c72237a78d241df447ad97d55f2d245d40ea4d3b7665b5c699e5273d3b8257f06d2a0a3a1d8d3bc0940158819f433d72b47460620a5c4ed756fad5d646
7
+ data.tar.gz: 4355818327a762070c48a8121728c9914b74881187f028c8dc8c440d46c9b51556621b5fb697cdbbd97fc93c3eaff03cafa69fefa6d84f6655023cb053336ae4
data/Makefile CHANGED
@@ -8,9 +8,14 @@ IGNORE = RubyEventStore.const_missing \
8
8
  RubyEventStore::Client::Within\#normalize_to_array \
9
9
  RubyEventStore::Client::Within\#add_thread_subscribers \
10
10
  RubyEventStore::Client::Within\#add_thread_global_subscribers \
11
- RubyEventStore::SerializedRecord \
12
- RubyEventStore::Projection\#read_events_from_stream \
13
- RubyEventStore::Projection\#read_events_from_all_streams
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
+ RubyEventStore::DeprecatedReadAPIRunner* \
18
+ RubyEventStore::DeprecatedReadAPIRewriter*
14
19
  SUBJECT ?= RubyEventStore*
15
20
 
16
21
  install: ## Install gem dependencies
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'ruby_event_store/deprecated_read_api_rewriter'
5
+ require 'ruby_event_store/deprecated_read_api_runner'
6
+ rescue LoadError
7
+ warn <<-EOS
8
+
9
+ You need following gems in Gemfile in order to use this script:
10
+
11
+ gem 'parser'
12
+ gem 'unparser'
13
+ gem 'astrolabe'
14
+
15
+ EOS
16
+ exit(2)
17
+ end
18
+
19
+ RubyEventStore::DeprecatedReadAPIRunner.go(ARGV)
@@ -15,4 +15,5 @@ require 'ruby_event_store/serialized_record'
15
15
  require 'ruby_event_store/mappers/default'
16
16
  require 'ruby_event_store/mappers/protobuf'
17
17
  require 'ruby_event_store/mappers/null_mapper'
18
+ require 'ruby_event_store/batch_enumerator'
18
19
  require 'ruby_event_store/version'
@@ -0,0 +1,25 @@
1
+ module RubyEventStore
2
+ class BatchEnumerator
3
+ def initialize(batch_size, total_limit, reader)
4
+ @batch_size = batch_size
5
+ @total_limit = total_limit
6
+ @reader = reader
7
+ end
8
+
9
+ def each
10
+ return to_enum unless block_given?
11
+ (0...total_limit).step(batch_size) do |batch_offset|
12
+ batch_offset = Integer(batch_offset)
13
+ batch_limit = [batch_size, total_limit - batch_offset].min
14
+ result = reader.call(batch_offset, batch_limit)
15
+
16
+ break if result.empty?
17
+ yield result
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_accessor :batch_size, :total_limit, :reader
24
+ end
25
+ end
@@ -45,79 +45,88 @@ module RubyEventStore
45
45
  end
46
46
 
47
47
  def read_events_forward(stream_name, start: :head, count: page_size)
48
- deserialized_events(read.stream(stream_name).limit(count).from(start).each)
48
+ warn <<~EOW
49
+ RubyEventStore::Client#read_events_forward has been deprecated.
50
+
51
+ Use following fluent API to receive exact results:
52
+ client.read.stream(stream_name).limit(count).from(start).each.to_a
53
+ EOW
54
+ read.stream(stream_name).limit(count).from(start).each.to_a
49
55
  end
50
56
 
51
57
  def read_events_backward(stream_name, start: :head, count: page_size)
52
- deserialized_events(read.stream(stream_name).limit(count).from(start).backward.each)
58
+ warn <<~EOW
59
+ RubyEventStore::Client#read_events_backward has been deprecated.
60
+
61
+ Use following fluent API to receive exact results:
62
+ client.read.stream(stream_name).limit(count).from(start).backward.each.to_a
63
+ EOW
64
+ read.stream(stream_name).limit(count).from(start).backward.each.to_a
53
65
  end
54
66
 
55
67
  def read_stream_events_forward(stream_name)
56
- deserialized_events(read.stream(stream_name).each)
68
+ warn <<~EOW
69
+ RubyEventStore::Client#read_stream_events_forward has been deprecated.
70
+
71
+ Use following fluent API to receive exact results:
72
+ client.read.stream(stream_name).each.to_a
73
+ EOW
74
+ read.stream(stream_name).each.to_a
57
75
  end
58
76
 
59
77
  def read_stream_events_backward(stream_name)
60
- deserialized_events(read.stream(stream_name).backward.each)
78
+ warn <<~EOW
79
+ RubyEventStore::Client#read_stream_events_backward has been deprecated.
80
+
81
+ Use following fluent API to receive exact results:
82
+ client.read.stream(stream_name).backward.each.to_a
83
+ EOW
84
+ read.stream(stream_name).backward.each.to_a
61
85
  end
62
86
 
63
87
  def read_all_streams_forward(start: :head, count: page_size)
64
- deserialized_events(read.limit(count).from(start).each)
88
+ warn <<~EOW
89
+ RubyEventStore::Client#read_all_streams_forward has been deprecated.
90
+
91
+ Use following fluent API to receive exact results:
92
+ client.read.limit(count).from(start).each.to_a
93
+ EOW
94
+ read.limit(count).from(start).each.to_a
65
95
  end
66
96
 
67
97
  def read_all_streams_backward(start: :head, count: page_size)
68
- deserialized_events(read.limit(count).from(start).backward.each)
98
+ warn <<~EOW
99
+ RubyEventStore::Client#read_all_streams_backward has been deprecated.
100
+
101
+ Use following fluent API to receive exact results:
102
+ client.read.limit(count).from(start).backward.each.to_a
103
+ EOW
104
+ read.limit(count).from(start).backward.each.to_a
69
105
  end
70
106
 
71
107
  def read_event(event_id)
72
108
  deserialize_event(repository.read_event(event_id))
73
109
  end
74
110
 
75
- DEPRECATED_WITHIN = "subscribe(subscriber, event_types, &task) has been deprecated. Use within(&task).subscribe(subscriber, to: event_types).call instead"
76
- DEPRECATED_TO = "subscribe(subscriber, event_types) has been deprecated. Use subscribe(subscriber, to: event_types) instead"
77
- # OLD:
78
- # subscribe(subscriber, event_types, &within)
79
- # subscribe(subscriber, event_types)
80
- # NEW:
81
- # subscribe(subscriber, to:)
82
- # subscribe(to:, &subscriber)
83
- def subscribe(subscriber = nil, event_types = nil, to: nil, &proc)
84
- if to
85
- raise ArgumentError, "subscriber must be first argument or block, cannot be both" if subscriber && proc
86
- raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber || proc
87
- raise ArgumentError, "list of event types must be second argument or named argument to: , it cannot be both" if event_types
88
- subscriber ||= proc
89
- event_broker.add_subscriber(subscriber, to)
90
- else
91
- if proc
92
- warn(DEPRECATED_WITHIN)
93
- within(&proc).subscribe(subscriber, to: event_types).call
94
- -> {}
95
- else
96
- warn(DEPRECATED_TO)
97
- subscribe(subscriber, to: event_types)
98
- end
99
- end
111
+ def read
112
+ Specification.new(repository, mapper)
100
113
  end
101
114
 
102
- DEPRECATED_ALL_WITHIN = "subscribe_to_all_events(subscriber, &task) has been deprecated. Use within(&task).subscribe_to_all_events(subscriber).call instead."
103
- # OLD:
104
- # subscribe_to_all_events(subscriber, &within)
105
- # subscribe_to_all_events(subscriber)
106
- # NEW:
107
- # subscribe_to_all_events(subscriber)
108
- # subscribe_to_all_events(&subscriber)
115
+ # subscribe(subscriber, to:)
116
+ # subscribe(to:, &subscriber)
117
+ def subscribe(subscriber = nil, to:, &proc)
118
+ raise ArgumentError, "subscriber must be first argument or block, cannot be both" if subscriber && proc
119
+ raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber || proc
120
+ subscriber ||= proc
121
+ event_broker.add_subscriber(subscriber, to)
122
+ end
123
+
124
+ # subscribe_to_all_events(subscriber)
125
+ # subscribe_to_all_events(&subscriber)
109
126
  def subscribe_to_all_events(subscriber = nil, &proc)
110
- if subscriber
111
- if proc
112
- warn(DEPRECATED_ALL_WITHIN)
113
- within(&proc).subscribe_to_all_events(subscriber).call
114
- -> {}
115
- else
116
- event_broker.add_global_subscriber(subscriber)
117
- end
118
- else
119
- event_broker.add_global_subscriber(proc)
120
- end
127
+ raise ArgumentError, "subscriber must be first argument or block, cannot be both" if subscriber && proc
128
+ raise SubscriberNotExist, "subscriber must be first argument or block" unless subscriber || proc
129
+ event_broker.add_global_subscriber(subscriber || proc)
121
130
  end
122
131
 
123
132
  class Within
@@ -188,20 +197,10 @@ module RubyEventStore
188
197
  end
189
198
  end
190
199
 
191
- def deserialized_events(serialized_events)
192
- serialized_events.map do |sev|
193
- deserialize_event(sev)
194
- end
195
- end
196
-
197
200
  def deserialize_event(sev)
198
201
  mapper.serialized_record_to_event(sev)
199
202
  end
200
203
 
201
- def read
202
- Specification.new(repository)
203
- end
204
-
205
204
  def normalize_to_array(events)
206
205
  return *events
207
206
  end
@@ -0,0 +1,67 @@
1
+ require 'parser/current'
2
+ require 'unparser'
3
+ require 'ruby_event_store'
4
+
5
+
6
+ module RubyEventStore
7
+ class DeprecatedReadAPIRewriter < ::Parser::Rewriter
8
+ def on_send(node)
9
+ node.each_descendant(:send) { |desc_node| on_send(desc_node) }
10
+
11
+ _, method_name, *args = node.children
12
+ replace_range = node.location.selector
13
+ replace_range = replace_range.join(node.location.end) if node.location.end
14
+
15
+ case method_name
16
+ when :read_all_streams_backward, :read_events_backward
17
+ rewrite_api("read.backward", replace_range, **parse_args(args))
18
+ when :read_stream_events_backward
19
+ rewrite_api("read.backward", replace_range, count: nil, **parse_args(args))
20
+ when :read_all_streams_forward, :read_events_forward
21
+ rewrite_api("read", replace_range, **parse_args(args))
22
+ when :read_stream_events_forward
23
+ rewrite_api("read", replace_range, count: nil, **parse_args(args))
24
+ end
25
+ end
26
+
27
+ def rewrite_api(query, range, start: nil, count: PAGE_SIZE, stream: nil)
28
+ query << ".stream(#{stream})" if stream
29
+ query << ".from(#{start})" if start
30
+ query << ".limit(#{count})" if count
31
+
32
+ replace(range, "#{query}.each.to_a")
33
+ end
34
+
35
+ def parse_args(args)
36
+ return {} if args.empty?
37
+
38
+ case args.size
39
+ when 1
40
+ case args[0].type
41
+ when :hash
42
+ stream_name, kwargs = nil, args[0]
43
+ else
44
+ stream_name, kwargs = parse_value(args[0]), AST::Node.new(:hash)
45
+ end
46
+ else
47
+ stream_name, kwargs = parse_value(args[0]), args[1]
48
+ end
49
+
50
+ kwargs
51
+ .children
52
+ .reduce({stream: stream_name}) do |memo, pair|
53
+ keyword, value = pair.children
54
+ memo[parse_keyword(keyword)] = parse_value(value)
55
+ memo
56
+ end
57
+ end
58
+
59
+ def parse_value(node)
60
+ Unparser.unparse(node)
61
+ end
62
+
63
+ def parse_keyword(node)
64
+ node.children[0].to_sym
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,64 @@
1
+ require 'parser/runner'
2
+ require 'tempfile'
3
+ require 'astrolabe/builder'
4
+
5
+
6
+ module RubyEventStore
7
+ class DeprecatedReadAPIRunner < Parser::Runner
8
+ attr_reader :rewriter, :parser_class, :modify
9
+
10
+ def initialize
11
+ super
12
+ @rewriter = DeprecatedReadAPIRewriter.new
13
+ end
14
+
15
+ def runner_name
16
+ "res-deprecated-read-api-migrator"
17
+ end
18
+
19
+ def setup_option_parsing(opts)
20
+ super(opts)
21
+
22
+ opts.on '-m', '--modify' do
23
+ @modify = true
24
+ end
25
+ end
26
+
27
+ def process(buffer)
28
+ parser = parser_class.new(Astrolabe::Builder.new)
29
+ new_source = rewriter.rewrite(buffer, parser.parse(buffer))
30
+ new_buffer = Parser::Source::Buffer.new(buffer.name + '|after res-deprecated-read-api-migrator')
31
+ new_buffer.source = new_source
32
+
33
+ if !modify
34
+ old = Tempfile.new('old')
35
+ old.write(buffer.source + "\n")
36
+ old.flush
37
+
38
+ new = Tempfile.new('new')
39
+ new.write(new_source + "\n")
40
+ new.flush
41
+
42
+ IO.popen("diff -u #{old.path} #{new.path}") do |io|
43
+ $stderr.write(
44
+ io.read
45
+ .sub(/^---.*/, "--- #{buffer.name}")
46
+ .sub(/^\+\+\+.*/, "+++ #{new_buffer.name}")
47
+ )
48
+ end
49
+ exit(1)
50
+ end
51
+
52
+ if File.exist?(buffer.name)
53
+ File.open(buffer.name, 'w') do |file|
54
+ file.write(new_source)
55
+ end
56
+ else
57
+ if input_size > 1
58
+ puts "Rewritten content of #{buffer.name}:"
59
+ end
60
+ puts new_source
61
+ end
62
+ end
63
+ end
64
+ end
@@ -9,6 +9,10 @@ module RubyEventStore
9
9
  end
10
10
  attr_reader :event_id, :metadata, :data
11
11
 
12
+ def message_id
13
+ event_id
14
+ end
15
+
12
16
  def type
13
17
  self.class.name
14
18
  end
@@ -43,6 +47,27 @@ module RubyEventStore
43
47
  ].hash ^ BIG_VALUE
44
48
  end
45
49
 
50
+ def correlation_id
51
+ metadata[:correlation_id]
52
+ end
53
+
54
+ def correlation_id=(val)
55
+ metadata[:correlation_id] = val
56
+ end
57
+
58
+ def causation_id
59
+ metadata[:causation_id]
60
+ end
61
+
62
+ def causation_id=(val)
63
+ metadata[:causation_id]= val
64
+ end
65
+
66
+ def correlate_with(other_message)
67
+ self.correlation_id = other_message.correlation_id || other_message.message_id
68
+ self.causation_id = other_message.message_id
69
+ end
70
+
46
71
  alias_method :eql?, :==
47
72
  end
48
73
  end
@@ -38,8 +38,14 @@ module RubyEventStore
38
38
  def read(spec)
39
39
  events = spec.global_stream? ? global : stream_of(spec.stream_name)
40
40
  events = events.reverse if spec.backward?
41
- events = read_batch(events, spec.start, spec.count) if spec.limit?
42
- events.each
41
+ events = events.drop(index_of(events, spec.start) + 1) unless spec.head?
42
+ events = events[0...spec.count] if spec.limit?
43
+ if spec.batched?
44
+ batch_reader = ->(offset, limit) { events.drop(offset).take(limit) }
45
+ BatchEnumerator.new(spec.batch_size, events.size, batch_reader).each
46
+ else
47
+ events.each
48
+ end
43
49
  end
44
50
 
45
51
  private
@@ -94,12 +100,6 @@ module RubyEventStore
94
100
  self
95
101
  end
96
102
 
97
- def read_batch(source, start_event_id, count)
98
- return source[0..count - 1] if start_event_id.equal?(:head)
99
- start_index = index_of(source, start_event_id)
100
- source[start_index + 1..start_index + count]
101
- end
102
-
103
103
  def index_of(source, event_id)
104
104
  source.index {|item| item.event_id.eql?(event_id)}
105
105
  end