event_store_client 0.2.3 → 0.2.4
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/event_store_client.rb +1 -9
- data/lib/event_store_client/broker.rb +4 -3
- data/lib/event_store_client/client.rb +13 -5
- data/lib/event_store_client/configuration.rb +36 -17
- data/lib/event_store_client/mapper/default.rb +2 -1
- data/lib/event_store_client/serializer/json.rb +2 -0
- data/lib/event_store_client/store_adapter/api/client.rb +65 -9
- data/lib/event_store_client/store_adapter/api/connection.rb +9 -5
- data/lib/event_store_client/store_adapter/in_memory.rb +40 -5
- data/lib/event_store_client/subscriptions.rb +2 -1
- data/lib/event_store_client/version.rb +1 -1
- metadata +21 -9
- data/lib/event_store_client/connection.rb +0 -112
- data/lib/event_store_client/endpoint.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc9b9f123804c920a08c07937465ae04afcd971d784912099f06822725742901
|
4
|
+
data.tar.gz: 0e5e5e7d863180a90fa20a6c6d1d2b8e76b479cb50489910af2327a33e0d2c7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04e46ab7a710fc53c7be0d22bbadd59e6a075495174b88447cb82f054de5dcfa02607a1bf7cc03392952bdabb6dffc68ec264575264bd1fb3a9d5ac32447caea
|
7
|
+
data.tar.gz: 188cff27182fe3e6f83250c70a3a4a5cab9814b7ef1ce61a624af2bcd235d4cf950723e7551d8ec2612f64923b117592341ea4ada03fe44660c6f2f7713f05ce
|
data/lib/event_store_client.rb
CHANGED
@@ -1,27 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module EventStoreClient
|
4
|
-
def self.configure(&block)
|
5
|
-
config = Configuration.instance
|
6
|
-
config.configure(&block)
|
7
|
-
end
|
8
4
|
end
|
9
5
|
|
10
|
-
require 'event_store_client/configuration'
|
11
6
|
require 'event_store_client/types'
|
12
7
|
require 'event_store_client/event'
|
13
8
|
require 'event_store_client/deserialized_event'
|
14
|
-
|
15
9
|
require 'event_store_client/serializer/json'
|
16
10
|
|
17
11
|
require 'event_store_client/mapper'
|
18
12
|
|
19
|
-
require 'event_store_client/
|
13
|
+
require 'event_store_client/configuration'
|
20
14
|
|
21
15
|
require 'event_store_client/store_adapter'
|
22
16
|
|
23
|
-
require 'event_store_client/connection'
|
24
|
-
|
25
17
|
require 'event_store_client/subscription'
|
26
18
|
require 'event_store_client/subscriptions'
|
27
19
|
require 'event_store_client/broker'
|
@@ -4,9 +4,10 @@ module EventStoreClient
|
|
4
4
|
class Broker
|
5
5
|
def call(subscriptions)
|
6
6
|
subscriptions.each do |subscription|
|
7
|
-
|
8
|
-
next if
|
9
|
-
|
7
|
+
res = connection.consume_feed(subscription.stream, subscription.name) || []
|
8
|
+
next if res[:events].none?
|
9
|
+
res[:events].each { |event| subscription.subscriber.call(event) }
|
10
|
+
connection.ack(res[:ack_uri])
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
@@ -8,13 +8,21 @@ module EventStoreClient
|
|
8
8
|
WrongExpectedEventVersion = Class.new(StandardError)
|
9
9
|
|
10
10
|
def publish(stream:, events:, expected_version: nil)
|
11
|
-
connection.
|
11
|
+
connection.append_to_stream(stream, events, expected_version: expected_version)
|
12
12
|
rescue StoreAdapter::Api::Client::WrongExpectedEventVersion => e
|
13
13
|
raise WrongExpectedEventVersion.new(e.message)
|
14
14
|
end
|
15
15
|
|
16
|
-
def read(stream, direction: 'forward', start: 0, all: false)
|
17
|
-
|
16
|
+
def read(stream, direction: 'forward', start: 0, all: false, resolve_links: true)
|
17
|
+
if all
|
18
|
+
connection.read_all_from_stream(
|
19
|
+
stream, start: start, direction: direction, resolve_links: resolve_links
|
20
|
+
)
|
21
|
+
else
|
22
|
+
connection.read(
|
23
|
+
stream, start: start, direction: direction, resolve_links: resolve_links
|
24
|
+
)
|
25
|
+
end
|
18
26
|
end
|
19
27
|
|
20
28
|
def subscribe(subscriber, to: [], polling: true)
|
@@ -81,12 +89,12 @@ module EventStoreClient
|
|
81
89
|
attr_reader :subscriptions, :broker, :error_handler
|
82
90
|
|
83
91
|
def config
|
84
|
-
EventStoreClient
|
92
|
+
EventStoreClient.config
|
85
93
|
end
|
86
94
|
|
87
95
|
def initialize
|
88
96
|
@threads = []
|
89
|
-
@connection ||=
|
97
|
+
@connection ||= EventStoreClient.adapter
|
90
98
|
@error_handler ||= config.error_handler
|
91
99
|
@service_name ||= 'default'
|
92
100
|
@broker ||= Broker.new(connection: connection)
|
@@ -1,28 +1,47 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dry-
|
4
|
-
require 'singleton'
|
3
|
+
require 'dry-configurable'
|
5
4
|
|
6
5
|
module EventStoreClient
|
7
|
-
|
8
|
-
include Singleton
|
6
|
+
extend Dry::Configurable
|
9
7
|
|
10
|
-
|
8
|
+
# Supported adapters: %i[api in_memory]
|
9
|
+
#
|
10
|
+
setting :adapter, :api
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
setting :error_handler
|
13
|
+
setting :eventstore_url, 'http://localhost:2113' do |value|
|
14
|
+
value.is_a?(URI) ? value : URI(value)
|
15
|
+
end
|
16
|
+
|
17
|
+
setting :eventstore_user, 'admin'
|
18
|
+
setting :eventstore_password, 'changeit'
|
19
|
+
|
20
|
+
setting :db_port, 2113
|
21
|
+
|
22
|
+
setting :per_page, 20
|
23
|
+
setting :pid_path, 'tmp/poll.pid'
|
15
24
|
|
16
|
-
|
25
|
+
setting :service_name, 'default'
|
17
26
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
27
|
+
setting :mapper, Mapper::Default.new
|
28
|
+
|
29
|
+
def self.configure
|
30
|
+
yield(config) if block_given?
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.adapter
|
34
|
+
case config.adapter
|
35
|
+
when :api
|
36
|
+
StoreAdapter::Api::Client.new(
|
37
|
+
config.eventstore_url,
|
38
|
+
per_page: config.per_page,
|
39
|
+
mapper: config.mapper,
|
40
|
+
connection_options: {}
|
41
|
+
)
|
42
|
+
else
|
43
|
+
StoreAdapter::InMemory.new(
|
44
|
+
mapper: config.mapper, per_page: config.per_page
|
26
45
|
)
|
27
46
|
end
|
28
47
|
end
|
@@ -5,7 +5,8 @@ module EventStoreClient
|
|
5
5
|
class Default
|
6
6
|
def serialize(event)
|
7
7
|
Event.new(
|
8
|
-
|
8
|
+
id: event.respond_to?(:id) ? event.id : nil,
|
9
|
+
type: (event.respond_to?(:type) ? event.type : nil) || event.class.to_s,
|
9
10
|
data: serializer.serialize(event.data),
|
10
11
|
metadata: serializer.serialize(event.metadata)
|
11
12
|
)
|
@@ -7,14 +7,16 @@ module EventStoreClient
|
|
7
7
|
WrongExpectedEventVersion = Class.new(StandardError)
|
8
8
|
|
9
9
|
def append_to_stream(stream_name, events, expected_version: nil)
|
10
|
+
serialized_events = events.map { |event| mapper.serialize(event) }
|
10
11
|
headers = {
|
11
12
|
'ES-ExpectedVersion' => expected_version&.to_s
|
12
13
|
}.reject { |_key, val| val.nil? || val.empty? }
|
13
14
|
|
14
|
-
data = build_events_data(
|
15
|
+
data = build_events_data(serialized_events)
|
15
16
|
response = make_request(:post, "/streams/#{stream_name}", body: data, headers: headers)
|
16
17
|
validate_response(response, expected_version)
|
17
18
|
response
|
19
|
+
serialized_events
|
18
20
|
end
|
19
21
|
|
20
22
|
def delete_stream(stream_name, hard_delete: false)
|
@@ -31,11 +33,39 @@ module EventStoreClient
|
|
31
33
|
'Accept' => 'application/vnd.eventstore.atom+json'
|
32
34
|
}
|
33
35
|
|
34
|
-
make_request(
|
36
|
+
response = make_request(
|
35
37
|
:get,
|
36
38
|
"/streams/#{stream_name}/#{start}/#{direction}/#{count}",
|
37
39
|
headers: headers
|
38
40
|
)
|
41
|
+
return [] if response.body.nil? || response.body.empty?
|
42
|
+
JSON.parse(response.body)['entries'].map do |entry|
|
43
|
+
deserialize_event(entry)
|
44
|
+
end.reverse
|
45
|
+
end
|
46
|
+
|
47
|
+
def read_all_from_stream(stream, start: 0, resolve_links: true)
|
48
|
+
count = per_page
|
49
|
+
events = []
|
50
|
+
failed_requests_count = 0
|
51
|
+
|
52
|
+
while failed_requests_count < 3
|
53
|
+
begin
|
54
|
+
response =
|
55
|
+
read(stream, start: start, direction: 'forward', resolve_links: resolve_links)
|
56
|
+
failed_requests_count += 1 && next unless response.success? || response.status == 404
|
57
|
+
rescue Faraday::ConnectionFailed
|
58
|
+
failed_requests_count += 1
|
59
|
+
next
|
60
|
+
end
|
61
|
+
failed_requests_count = 0
|
62
|
+
break if response.body.nil? || response.body.empty?
|
63
|
+
entries = JSON.parse(response.body)['entries']
|
64
|
+
break if entries.empty?
|
65
|
+
events += entries.map { |entry| deserialize_event(entry) }.reverse
|
66
|
+
start += count
|
67
|
+
end
|
68
|
+
events
|
39
69
|
end
|
40
70
|
|
41
71
|
def join_streams(name, streams)
|
@@ -79,18 +109,31 @@ module EventStoreClient
|
|
79
109
|
subscription_name,
|
80
110
|
count: 1,
|
81
111
|
long_poll: 0,
|
82
|
-
resolve_links: true
|
112
|
+
resolve_links: true,
|
113
|
+
per_page: 20
|
83
114
|
)
|
84
115
|
headers = long_poll.positive? ? { 'ES-LongPoll' => long_poll.to_s } : {}
|
85
116
|
headers['Content-Type'] = 'application/vnd.eventstore.competingatom+json'
|
86
117
|
headers['Accept'] = 'application/vnd.eventstore.competingatom+json'
|
87
118
|
headers['ES-ResolveLinktos'] = resolve_links.to_s
|
88
119
|
|
89
|
-
make_request(
|
120
|
+
response = make_request(
|
90
121
|
:get,
|
91
122
|
"/subscriptions/#{stream_name}/#{subscription_name}/#{count}",
|
92
123
|
headers: headers
|
93
124
|
)
|
125
|
+
|
126
|
+
return [] if response.body || response.body.empty?
|
127
|
+
|
128
|
+
body = JSON.parse(response.body)
|
129
|
+
|
130
|
+
ack_info = body['links'].find { |link| link['relation'] == 'ackAll' }
|
131
|
+
return unless ack_info
|
132
|
+
ack_uri = ack_info['uri']
|
133
|
+
events = body['entries'].map do |entry|
|
134
|
+
deserialize_event(entry)
|
135
|
+
end
|
136
|
+
{ ack_uri: ack_uri, events: events }
|
94
137
|
end
|
95
138
|
|
96
139
|
def link_to(stream_name, events, expected_version: nil)
|
@@ -106,7 +149,7 @@ module EventStoreClient
|
|
106
149
|
headers: headers
|
107
150
|
)
|
108
151
|
validate_response(response, expected_version)
|
109
|
-
|
152
|
+
true
|
110
153
|
end
|
111
154
|
|
112
155
|
def ack(url)
|
@@ -115,11 +158,12 @@ module EventStoreClient
|
|
115
158
|
|
116
159
|
private
|
117
160
|
|
118
|
-
attr_reader :
|
161
|
+
attr_reader :uri, :per_page, :connection_options, :mapper
|
119
162
|
|
120
|
-
def initialize(
|
121
|
-
@
|
163
|
+
def initialize(uri, per_page: 20, mapper:, connection_options: {})
|
164
|
+
@uri = uri
|
122
165
|
@per_page = per_page
|
166
|
+
@mapper = mapper
|
123
167
|
@connection_options = connection_options
|
124
168
|
end
|
125
169
|
|
@@ -154,7 +198,7 @@ module EventStoreClient
|
|
154
198
|
end
|
155
199
|
|
156
200
|
def connection
|
157
|
-
@connection ||= Api::Connection.new(
|
201
|
+
@connection ||= Api::Connection.new(uri, connection_options).call
|
158
202
|
end
|
159
203
|
|
160
204
|
def validate_response(resp, expected_version)
|
@@ -164,6 +208,18 @@ module EventStoreClient
|
|
164
208
|
"expected: #{expected_version}"
|
165
209
|
)
|
166
210
|
end
|
211
|
+
|
212
|
+
def deserialize_event(entry)
|
213
|
+
event = EventStoreClient::Event.new(
|
214
|
+
id: entry['eventId'],
|
215
|
+
title: entry['title'],
|
216
|
+
type: entry['eventType'],
|
217
|
+
data: entry['data'] || '{}',
|
218
|
+
metadata: entry['isMetaData'] ? entry['metaData'] : '{}'
|
219
|
+
)
|
220
|
+
|
221
|
+
mapper.deserialize(event)
|
222
|
+
end
|
167
223
|
end
|
168
224
|
end
|
169
225
|
end
|
@@ -9,23 +9,27 @@ module EventStoreClient
|
|
9
9
|
def call
|
10
10
|
Faraday.new(
|
11
11
|
{
|
12
|
-
url:
|
12
|
+
url: uri.to_s,
|
13
13
|
headers: DEFAULT_HEADERS
|
14
14
|
}.merge(options)
|
15
15
|
) do |conn|
|
16
|
-
conn.basic_auth(
|
16
|
+
conn.basic_auth(config.eventstore_user, config.eventstore_password)
|
17
17
|
conn.adapter Faraday.default_adapter
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
def
|
24
|
-
|
23
|
+
def config
|
24
|
+
EventStoreClient.config
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(uri, options = {})
|
28
|
+
@uri = uri
|
25
29
|
@options = options
|
26
30
|
end
|
27
31
|
|
28
|
-
attr_reader :
|
32
|
+
attr_reader :uri, :options
|
29
33
|
|
30
34
|
DEFAULT_HEADERS = {
|
31
35
|
'Content-Type' => 'application/vnd.eventstore.events+json'
|
@@ -33,7 +33,27 @@ module EventStoreClient
|
|
33
33
|
read_stream_backward(stream_name, start: start)
|
34
34
|
end
|
35
35
|
|
36
|
-
Response.new(response.to_json, 200)
|
36
|
+
res = Response.new(response.to_json, 200)
|
37
|
+
|
38
|
+
return [] if res.body.nil? || res.body.empty?
|
39
|
+
JSON.parse(res.body)['entries'].map do |entry|
|
40
|
+
deserialize_event(entry)
|
41
|
+
end.reverse
|
42
|
+
end
|
43
|
+
|
44
|
+
def read_all_from_stream(stream_name, direction: 'forward', start: 0, resolve_links: true)
|
45
|
+
response =
|
46
|
+
if direction == 'forward'
|
47
|
+
read_stream_forward(stream_name, start: start)
|
48
|
+
else
|
49
|
+
read_stream_backward(stream_name, start: start)
|
50
|
+
end
|
51
|
+
res = Response.new(response.to_json, 200)
|
52
|
+
|
53
|
+
return [] if res.body.nil? || res.body.empty?
|
54
|
+
JSON.parse(res.body)['entries'].map do |entry|
|
55
|
+
deserialize_event(entry)
|
56
|
+
end.reverse
|
37
57
|
end
|
38
58
|
|
39
59
|
def subscribe_to_stream(stream_name, subscription_name, **)
|
@@ -54,6 +74,7 @@ module EventStoreClient
|
|
54
74
|
|
55
75
|
def link_to(stream_name, events, **)
|
56
76
|
append_to_stream(stream_name, events)
|
77
|
+
events
|
57
78
|
end
|
58
79
|
|
59
80
|
def ack(url)
|
@@ -64,11 +85,11 @@ module EventStoreClient
|
|
64
85
|
|
65
86
|
private
|
66
87
|
|
67
|
-
attr_reader :
|
88
|
+
attr_reader :per_page, :mapper
|
68
89
|
|
69
|
-
def initialize(
|
70
|
-
@endpoint = Endpoint.new(host: host, port: port)
|
90
|
+
def initialize(mapper:, per_page: 20)
|
71
91
|
@per_page = per_page
|
92
|
+
@mapper = mapper
|
72
93
|
@event_store = {}
|
73
94
|
end
|
74
95
|
|
@@ -115,11 +136,25 @@ module EventStoreClient
|
|
115
136
|
else
|
116
137
|
[{
|
117
138
|
'uri' =>
|
118
|
-
"
|
139
|
+
"/streams/#{stream_name}/#{batch_size}/#{direction}/#{count}",
|
119
140
|
'relation' => direction
|
120
141
|
}]
|
121
142
|
end
|
122
143
|
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
def deserialize_event(entry)
|
148
|
+
event = EventStoreClient::Event.new(
|
149
|
+
id: entry['eventId'],
|
150
|
+
title: entry['title'],
|
151
|
+
type: entry['eventType'],
|
152
|
+
data: entry['data'] || '{}',
|
153
|
+
metadata: entry['isMetaData'] ? entry['metaData'] : '{}'
|
154
|
+
)
|
155
|
+
|
156
|
+
mapper.deserialize(event)
|
157
|
+
end
|
123
158
|
end
|
124
159
|
end
|
125
160
|
end
|
@@ -25,8 +25,9 @@ module EventStoreClient
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def create_subscription(subscription)
|
28
|
+
# store position somewhere.
|
28
29
|
connection.join_streams(subscription.name, subscription.observed_streams)
|
29
|
-
connection.
|
30
|
+
connection.subscribe_to_stream(subscription.stream, name: subscription.name)
|
30
31
|
end
|
31
32
|
|
32
33
|
attr_reader :connection, :subscriptions, :service
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: event_store_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Wilgosz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-schema
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: faraday
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '1.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: '1.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rss
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.2.8
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: dry-configurable
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.11'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.11'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,12 +122,10 @@ files:
|
|
108
122
|
- lib/event_store_client/broker.rb
|
109
123
|
- lib/event_store_client/client.rb
|
110
124
|
- lib/event_store_client/configuration.rb
|
111
|
-
- lib/event_store_client/connection.rb
|
112
125
|
- lib/event_store_client/data_decryptor.rb
|
113
126
|
- lib/event_store_client/data_encryptor.rb
|
114
127
|
- lib/event_store_client/deserialized_event.rb
|
115
128
|
- lib/event_store_client/encryption_metadata.rb
|
116
|
-
- lib/event_store_client/endpoint.rb
|
117
129
|
- lib/event_store_client/event.rb
|
118
130
|
- lib/event_store_client/mapper.rb
|
119
131
|
- lib/event_store_client/mapper/default.rb
|
@@ -148,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
160
|
- !ruby/object:Gem::Version
|
149
161
|
version: '0'
|
150
162
|
requirements: []
|
151
|
-
rubygems_version: 3.
|
163
|
+
rubygems_version: 3.1.4
|
152
164
|
signing_key:
|
153
165
|
specification_version: 4
|
154
166
|
summary: Ruby integration for https://eventstore.org
|
@@ -1,112 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
class Connection
|
5
|
-
def publish(stream:, events:, expected_version: nil)
|
6
|
-
serialized_events = events.map { |event| mapper.serialize(event) }
|
7
|
-
client.append_to_stream(
|
8
|
-
stream, serialized_events, expected_version: expected_version
|
9
|
-
)
|
10
|
-
serialized_events
|
11
|
-
end
|
12
|
-
|
13
|
-
def read(stream, direction:, start:, all:, resolve_links: true)
|
14
|
-
return read_all_from_stream(stream, start: start, resolve_links: resolve_links) if all
|
15
|
-
read_from_stream(
|
16
|
-
stream, direction: direction, start: start, resolve_links: resolve_links
|
17
|
-
)
|
18
|
-
end
|
19
|
-
|
20
|
-
def delete_stream(stream); end
|
21
|
-
|
22
|
-
def join_streams(name, streams)
|
23
|
-
client.join_streams(name, streams)
|
24
|
-
end
|
25
|
-
|
26
|
-
def subscribe(stream, name:)
|
27
|
-
client.subscribe_to_stream(stream, name)
|
28
|
-
end
|
29
|
-
|
30
|
-
def consume_feed(stream, subscription)
|
31
|
-
response = client.consume_feed(stream, subscription)
|
32
|
-
return [] unless response.body
|
33
|
-
body = JSON.parse(response.body)
|
34
|
-
|
35
|
-
ack = body['links'].find { |link| link['relation'] == 'ackAll' }
|
36
|
-
return unless ack
|
37
|
-
ack_uri = ack['uri']
|
38
|
-
events = body['entries'].map do |entry|
|
39
|
-
deserialize_event(entry)
|
40
|
-
end
|
41
|
-
client.ack(ack_uri)
|
42
|
-
events
|
43
|
-
end
|
44
|
-
|
45
|
-
def link_to(stream, events, expected_version: nil)
|
46
|
-
client.link_to(stream, events, expected_version: expected_version)
|
47
|
-
|
48
|
-
true
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
attr_reader :mapper, :per_page, :client
|
54
|
-
|
55
|
-
def config
|
56
|
-
EventStoreClient::Configuration.instance
|
57
|
-
end
|
58
|
-
|
59
|
-
def initialize
|
60
|
-
@per_page = config.per_page
|
61
|
-
@mapper = config.mapper
|
62
|
-
@client = config.adapter
|
63
|
-
end
|
64
|
-
|
65
|
-
def read_from_stream(stream, direction:, start:, resolve_links:)
|
66
|
-
response =
|
67
|
-
client.read(
|
68
|
-
stream, start: start, direction: direction, resolve_links: resolve_links
|
69
|
-
)
|
70
|
-
return [] if response.body.nil? || response.body.empty?
|
71
|
-
JSON.parse(response.body)['entries'].map do |entry|
|
72
|
-
deserialize_event(entry)
|
73
|
-
end.reverse
|
74
|
-
end
|
75
|
-
|
76
|
-
def read_all_from_stream(stream, start:, resolve_links:)
|
77
|
-
count = per_page
|
78
|
-
events = []
|
79
|
-
failed_requests_count = 0
|
80
|
-
|
81
|
-
while failed_requests_count < 3
|
82
|
-
begin
|
83
|
-
response =
|
84
|
-
client.read(stream, start: start, direction: 'forward', resolve_links: resolve_links)
|
85
|
-
failed_requests_count += 1 && next unless response.success? || response.status == 404
|
86
|
-
rescue Faraday::ConnectionFailed
|
87
|
-
failed_requests_count += 1
|
88
|
-
next
|
89
|
-
end
|
90
|
-
failed_requests_count = 0
|
91
|
-
break if response.body.nil? || response.body.empty?
|
92
|
-
entries = JSON.parse(response.body)['entries']
|
93
|
-
break if entries.empty?
|
94
|
-
events += entries.map { |entry| deserialize_event(entry) }.reverse
|
95
|
-
start += count
|
96
|
-
end
|
97
|
-
events
|
98
|
-
end
|
99
|
-
|
100
|
-
def deserialize_event(entry)
|
101
|
-
event = EventStoreClient::Event.new(
|
102
|
-
id: entry['eventId'],
|
103
|
-
title: entry['title'],
|
104
|
-
type: entry['eventType'],
|
105
|
-
data: entry['data'] || '{}',
|
106
|
-
metadata: entry['isMetaData'] ? entry['metaData'] : '{}'
|
107
|
-
)
|
108
|
-
|
109
|
-
mapper.deserialize(event)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|