ruby_event_store 0.29.0 → 0.30.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: 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