event_store_client 2.2.0 → 2.3.0.pre.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/docs/configuration.md +47 -0
- data/lib/event_store_client/adapters/grpc/client.rb +22 -12
- data/lib/event_store_client/adapters/grpc/cluster/gossip_discover.rb +10 -3
- data/lib/event_store_client/adapters/grpc/cluster/queryless_discover.rb +8 -2
- data/lib/event_store_client/adapters/grpc/commands/command.rb +7 -5
- data/lib/event_store_client/adapters/grpc/commands/streams/append_multiple.rb +3 -1
- data/lib/event_store_client/adapters/grpc/commands/streams/link_to.rb +1 -1
- data/lib/event_store_client/adapters/grpc/commands/streams/link_to_multiple.rb +1 -2
- data/lib/event_store_client/adapters/grpc/commands/streams/read.rb +5 -2
- data/lib/event_store_client/adapters/grpc/commands/streams/read_paginated.rb +8 -6
- data/lib/event_store_client/adapters/grpc/commands/streams/subscribe.rb +5 -2
- data/lib/event_store_client/adapters/grpc/connection.rb +20 -14
- data/lib/event_store_client/adapters/grpc/discover.rb +47 -27
- data/lib/event_store_client/adapters/grpc/options/streams/read_options.rb +5 -5
- data/lib/event_store_client/adapters/grpc/shared/streams/process_response.rb +8 -1
- data/lib/event_store_client/adapters/grpc/shared/streams/process_responses.rb +8 -1
- data/lib/event_store_client/config.rb +2 -1
- data/lib/event_store_client/data_decryptor.rb +0 -2
- data/lib/event_store_client/mapper/default.rb +8 -4
- data/lib/event_store_client/mapper/encrypted.rb +10 -7
- data/lib/event_store_client/serializer/event_deserializer.rb +7 -9
- data/lib/event_store_client/version.rb +1 -1
- data/lib/event_store_client.rb +32 -7
- metadata +4 -5
- data/lib/event_store_client/configuration.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96e1f2743b3265c8776ffe39636f086af2be0bc19ff46e693f1fbf7373eeb3d4
|
4
|
+
data.tar.gz: 7595e367ccced285bb4e061d9875bf6ba84d9e999aa60f404609f0258aea1426
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88e2b3324a0b59773f39077ad954e8a0f98ca0fd0bd67217a67c742bdc5ae6efbdf36878a0feeff9e2532e8f1d97f5a6eee0581268dc24cda631728fe5fc65d3
|
7
|
+
data.tar.gz: 73be7b894f397e323807adec3667b78ddc7f7b5973942cb7d77cb5872af1d6b01eee9f9e7c7440db213d3ea3fb23256e99066ce4d0e23af3c26bbd14c3c4bb56
|
data/docs/configuration.md
CHANGED
@@ -128,3 +128,50 @@ esdb://localhost:2113/?tls=false
|
|
128
128
|
esdb+discover://localhost:2113/?grpcRetryAttempts=3&grpcRetryInterval=300&discoverInterval=200
|
129
129
|
esdb://localhost:2113,localhost:2114,localhost:2115/?gossipTimeout=500&maxDiscoverAttempts=3
|
130
130
|
```
|
131
|
+
|
132
|
+
### Multiple configurations
|
133
|
+
|
134
|
+
`event_store_client` provides a possibility to configure as much connections as you want. To do so, you have to name your configuration, and later provide that name to `EventStoreClient` client.
|
135
|
+
|
136
|
+
Setup your configs:
|
137
|
+
```ruby
|
138
|
+
EventStoreClient.configure(name: :es_db_1) do |config|
|
139
|
+
# adjust your config here
|
140
|
+
config.eventstore_url = 'esdb://localhost:2113'
|
141
|
+
end
|
142
|
+
EventStoreClient.configure(name: :es_db_2) do |config|
|
143
|
+
# adjust your second config here
|
144
|
+
config.eventstore_url = 'esdb://localhost:2114'
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
148
|
+
Tell `EventStoreClient` which config you want to use:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
client1 = EventStoreClient.client(config_name: :es_db_1)
|
152
|
+
client2 = EventStoreClient.client(config_name: :es_db_2)
|
153
|
+
# Read from $all stream using :es_db_1 config
|
154
|
+
client1.read('$all')
|
155
|
+
# Read from $all stream using :es_db_2 config
|
156
|
+
client2.read('$all')
|
157
|
+
```
|
158
|
+
|
159
|
+
#### Default config
|
160
|
+
|
161
|
+
If you only have one config - you don't have to bother naming it or passing a config name to the client when performing any operations. You can configure it as usual.
|
162
|
+
|
163
|
+
Setup your default config:
|
164
|
+
```ruby
|
165
|
+
EventStoreClient.configure do |config|
|
166
|
+
# config goes here
|
167
|
+
config.eventstore_url = 'esdb://localhost:2113'
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
Use it:
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
client = EventStoreClient.client
|
175
|
+
# Read from $all stream using your default config
|
176
|
+
client.read('$all')
|
177
|
+
```
|
@@ -5,7 +5,13 @@
|
|
5
5
|
module EventStoreClient
|
6
6
|
module GRPC
|
7
7
|
class Client
|
8
|
-
|
8
|
+
attr_reader :config
|
9
|
+
private :config
|
10
|
+
|
11
|
+
# @param config [EventStoreClient::Config]
|
12
|
+
def initialize(config)
|
13
|
+
@config = config
|
14
|
+
end
|
9
15
|
|
10
16
|
# @param stream_name [String]
|
11
17
|
# @param events_or_event [EventStoreClient::DeserializedEvent, Array<EventStoreClient::DeserializedEvent>]
|
@@ -30,11 +36,11 @@ module EventStoreClient
|
|
30
36
|
# Returns monads' Success/Failure in case whether request was performed.
|
31
37
|
def append_to_stream(stream_name, events_or_event, options: {}, credentials: {}, &blk)
|
32
38
|
if events_or_event.is_a?(Array)
|
33
|
-
Commands::Streams::AppendMultiple.new(**credentials).call(
|
39
|
+
Commands::Streams::AppendMultiple.new(config: config, **credentials).call(
|
34
40
|
stream_name, events_or_event, options: options
|
35
41
|
)
|
36
42
|
else
|
37
|
-
Commands::Streams::Append.new(**credentials).call(
|
43
|
+
Commands::Streams::Append.new(config: config, **credentials).call(
|
38
44
|
stream_name, events_or_event, options: options, &blk
|
39
45
|
)
|
40
46
|
end
|
@@ -91,7 +97,7 @@ module EventStoreClient
|
|
91
97
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
92
98
|
def read(stream_name, options: {}, skip_deserialization: config.skip_deserialization,
|
93
99
|
skip_decryption: config.skip_decryption, credentials: {}, &blk)
|
94
|
-
Commands::Streams::Read.new(**credentials).call(
|
100
|
+
Commands::Streams::Read.new(config: config, **credentials).call(
|
95
101
|
stream_name,
|
96
102
|
options: options,
|
97
103
|
skip_deserialization: skip_deserialization,
|
@@ -106,7 +112,7 @@ module EventStoreClient
|
|
106
112
|
def read_paginated(stream_name, options: {}, credentials: {},
|
107
113
|
skip_deserialization: config.skip_deserialization,
|
108
114
|
skip_decryption: config.skip_decryption, &blk)
|
109
|
-
Commands::Streams::ReadPaginated.new(**credentials).call(
|
115
|
+
Commands::Streams::ReadPaginated.new(config: config, **credentials).call(
|
110
116
|
stream_name,
|
111
117
|
options: options,
|
112
118
|
skip_deserialization: skip_deserialization,
|
@@ -133,7 +139,9 @@ module EventStoreClient
|
|
133
139
|
# ```
|
134
140
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
135
141
|
def hard_delete_stream(stream_name, options: {}, credentials: {}, &blk)
|
136
|
-
Commands::Streams::HardDelete.
|
142
|
+
Commands::Streams::HardDelete.
|
143
|
+
new(config: config, **credentials).
|
144
|
+
call(stream_name, options: options, &blk)
|
137
145
|
end
|
138
146
|
|
139
147
|
# Refs https://developers.eventstore.com/server/v5/streams.html#soft-delete-and-truncatebefore
|
@@ -154,7 +162,9 @@ module EventStoreClient
|
|
154
162
|
# ```
|
155
163
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
156
164
|
def delete_stream(stream_name, options: {}, credentials: {}, &blk)
|
157
|
-
Commands::Streams::Delete.
|
165
|
+
Commands::Streams::Delete.
|
166
|
+
new(config: config, **credentials).
|
167
|
+
call(stream_name, options: options, &blk)
|
158
168
|
end
|
159
169
|
|
160
170
|
# Subscribe to the given stream and listens for events. Note, that it will block execution of
|
@@ -213,7 +223,7 @@ module EventStoreClient
|
|
213
223
|
def subscribe_to_stream(stream_name, handler:, options: {}, credentials: {},
|
214
224
|
skip_deserialization: config.skip_deserialization,
|
215
225
|
skip_decryption: config.skip_decryption, &blk)
|
216
|
-
Commands::Streams::Subscribe.new(**credentials).call(
|
226
|
+
Commands::Streams::Subscribe.new(config: config, **credentials).call(
|
217
227
|
stream_name,
|
218
228
|
handler: handler,
|
219
229
|
options: options,
|
@@ -229,7 +239,7 @@ module EventStoreClient
|
|
229
239
|
def subscribe_to_all(handler:, options: {}, credentials: {},
|
230
240
|
skip_deserialization: config.skip_deserialization,
|
231
241
|
skip_decryption: config.skip_decryption, &blk)
|
232
|
-
Commands::Streams::Subscribe.new(**credentials).call(
|
242
|
+
Commands::Streams::Subscribe.new(config: config, **credentials).call(
|
233
243
|
'$all',
|
234
244
|
handler: handler,
|
235
245
|
options: options,
|
@@ -246,14 +256,14 @@ module EventStoreClient
|
|
246
256
|
# @see #append_to_stream for available params and returned value
|
247
257
|
def link_to(stream_name, events_or_event, options: {}, credentials: {}, &blk)
|
248
258
|
if events_or_event.is_a?(Array)
|
249
|
-
Commands::Streams::LinkToMultiple.new(**credentials).call(
|
259
|
+
Commands::Streams::LinkToMultiple.new(config: config, **credentials).call(
|
250
260
|
stream_name,
|
251
261
|
events_or_event,
|
252
262
|
options: options,
|
253
263
|
&blk
|
254
264
|
)
|
255
265
|
else
|
256
|
-
Commands::Streams::LinkTo.new(**credentials).call(
|
266
|
+
Commands::Streams::LinkTo.new(config: config, **credentials).call(
|
257
267
|
stream_name,
|
258
268
|
events_or_event,
|
259
269
|
options: options,
|
@@ -267,7 +277,7 @@ module EventStoreClient
|
|
267
277
|
# @option credentials [String] :password
|
268
278
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
269
279
|
def cluster_info(credentials: {})
|
270
|
-
Commands::Gossip::ClusterInfo.new(**credentials).call
|
280
|
+
Commands::Gossip::ClusterInfo.new(config: config, **credentials).call
|
271
281
|
end
|
272
282
|
end
|
273
283
|
end
|
@@ -6,8 +6,6 @@ module EventStoreClient
|
|
6
6
|
module GRPC
|
7
7
|
module Cluster
|
8
8
|
class GossipDiscover
|
9
|
-
include Configuration
|
10
|
-
|
11
9
|
DiscoverError = Class.new(StandardError)
|
12
10
|
|
13
11
|
# Order is important - it plays role of states priority as well
|
@@ -15,6 +13,14 @@ module EventStoreClient
|
|
15
13
|
ALLOWED_NODE_STATES =
|
16
14
|
(%i[Leader Follower] + READ_ONLY_STATES).freeze
|
17
15
|
|
16
|
+
attr_reader :config
|
17
|
+
private :config
|
18
|
+
|
19
|
+
# @param config [EventStoreClient::Config]
|
20
|
+
def initialize(config:)
|
21
|
+
@config = config
|
22
|
+
end
|
23
|
+
|
18
24
|
# @param nodes [Array<EventStoreClient::Connection::Url::Node>]
|
19
25
|
# @param failed_member [EventStoreClient::GRPC::Cluster::Member, nil]
|
20
26
|
# @return [EventStoreClient::GRPC::Cluster::Member]
|
@@ -58,7 +64,8 @@ module EventStoreClient
|
|
58
64
|
connection = Connection.new(
|
59
65
|
host: node.host,
|
60
66
|
port: node.port,
|
61
|
-
timeout: config.eventstore_url.gossip_timeout
|
67
|
+
timeout: config.eventstore_url.gossip_timeout,
|
68
|
+
config: config
|
62
69
|
)
|
63
70
|
members =
|
64
71
|
connection.
|
@@ -4,10 +4,16 @@ module EventStoreClient
|
|
4
4
|
module GRPC
|
5
5
|
module Cluster
|
6
6
|
class QuerylessDiscover
|
7
|
-
include Configuration
|
8
|
-
|
9
7
|
NoHostError = Class.new(StandardError)
|
10
8
|
|
9
|
+
attr_reader :config
|
10
|
+
private :config
|
11
|
+
|
12
|
+
# @param config [EventStoreClient::Config]
|
13
|
+
def initialize(config:)
|
14
|
+
@config = config
|
15
|
+
end
|
16
|
+
|
11
17
|
# @param nodes [EventStoreClient::Connection::Url::Node]
|
12
18
|
# @return [EventStoreClient::GRPC::Cluster::Member]
|
13
19
|
def call(nodes)
|
@@ -14,19 +14,20 @@ module EventStoreClient
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
include Configuration
|
18
17
|
include Dry::Monads[:try, :result]
|
19
18
|
|
20
|
-
attr_reader :connection
|
21
|
-
private :connection
|
19
|
+
attr_reader :connection, :config
|
20
|
+
private :connection, :config
|
22
21
|
|
22
|
+
# @param config [EventStoreClient::Config]
|
23
23
|
# @param conn_options [Hash]
|
24
24
|
# @option conn_options [String] :host
|
25
25
|
# @option conn_options [Integer] :port
|
26
26
|
# @option conn_options [String] :username
|
27
27
|
# @option conn_options [String] :password
|
28
|
-
def initialize(**conn_options)
|
29
|
-
@
|
28
|
+
def initialize(config:, **conn_options)
|
29
|
+
@config = config
|
30
|
+
@connection = EventStoreClient::GRPC::Connection.new(config: config, **conn_options)
|
30
31
|
end
|
31
32
|
|
32
33
|
# Override it in your implementation of command.
|
@@ -74,6 +75,7 @@ module EventStoreClient
|
|
74
75
|
config.logger&.debug("Request failed. Reason: #{e.class}. Retying.")
|
75
76
|
retry
|
76
77
|
end
|
78
|
+
Discover.current_member(config: config)&.failed_endpoint = true
|
77
79
|
raise
|
78
80
|
end
|
79
81
|
end
|
@@ -12,7 +12,9 @@ module EventStoreClient
|
|
12
12
|
def call(stream_name, events, options:, &blk)
|
13
13
|
result = []
|
14
14
|
events.each.with_index do |event, index|
|
15
|
-
response = Commands::Streams::Append.new(
|
15
|
+
response = Commands::Streams::Append.new(
|
16
|
+
config: config, **connection_options
|
17
|
+
).call(
|
16
18
|
stream_name, event, options: options
|
17
19
|
) do |req_opts, proposed_msg_opts|
|
18
20
|
req_opts.options.revision += index if has_revision_option?(req_opts.options)
|
@@ -7,7 +7,7 @@ module EventStoreClient
|
|
7
7
|
class LinkTo < Command
|
8
8
|
# @see {EventStoreClient::GRPC::Client#hard_delete_stream}
|
9
9
|
def call(stream_name, event, options:, &blk)
|
10
|
-
append_cmd = Append.new(**connection_options)
|
10
|
+
append_cmd = Append.new(config: config, **connection_options)
|
11
11
|
link_event = DeserializedEvent.new(
|
12
12
|
id: event.id, type: DeserializedEvent::LINK_TYPE, data: event.title
|
13
13
|
)
|
@@ -11,12 +11,11 @@ module EventStoreClient
|
|
11
11
|
# @see {EventStoreClient::GRPC::Client#link_to}
|
12
12
|
def call(stream_name, events, options:, &blk)
|
13
13
|
result = []
|
14
|
-
link_cmd = Commands::Streams::LinkTo.new(**connection_options)
|
14
|
+
link_cmd = Commands::Streams::LinkTo.new(config: config, **connection_options)
|
15
15
|
events.each.with_index do |event, index|
|
16
16
|
response =
|
17
17
|
link_cmd.call(stream_name, event, options: options) do |req_opts, proposed_msg_opts|
|
18
18
|
req_opts.options.revision += index if has_revision_option?(req_opts.options)
|
19
|
-
|
20
19
|
yield(req_opts, proposed_msg_opts) if blk
|
21
20
|
end
|
22
21
|
result.push(response)
|
@@ -15,7 +15,7 @@ module EventStoreClient
|
|
15
15
|
yield options if block_given?
|
16
16
|
result =
|
17
17
|
retry_request { service.read(request.new(options: options), metadata: metadata).to_a }
|
18
|
-
EventStoreClient::GRPC::Shared::Streams::ProcessResponses.new.call(
|
18
|
+
EventStoreClient::GRPC::Shared::Streams::ProcessResponses.new(config: config).call(
|
19
19
|
result,
|
20
20
|
skip_deserialization,
|
21
21
|
skip_decryption
|
@@ -28,7 +28,10 @@ module EventStoreClient
|
|
28
28
|
# @param options [Hash]
|
29
29
|
# @return [EventStore::Client::Streams::ReadReq::Options]
|
30
30
|
def normalize_options(stream_name, options)
|
31
|
-
options =
|
31
|
+
options =
|
32
|
+
Options::Streams::ReadOptions.
|
33
|
+
new(stream_name, options, config: config).
|
34
|
+
request_options
|
32
35
|
EventStore::Client::Streams::ReadReq::Options.new(options)
|
33
36
|
end
|
34
37
|
end
|
@@ -22,7 +22,7 @@ module EventStoreClient
|
|
22
22
|
Enumerator.new do |yielder|
|
23
23
|
loop do
|
24
24
|
response =
|
25
|
-
Read.new(**connection_options).call(
|
25
|
+
Read.new(config: config, **connection_options).call(
|
26
26
|
stream_name,
|
27
27
|
options: options,
|
28
28
|
skip_deserialization: true,
|
@@ -45,11 +45,13 @@ module EventStoreClient
|
|
45
45
|
raise StopIteration
|
46
46
|
end
|
47
47
|
processed_response =
|
48
|
-
EventStoreClient::GRPC::Shared::Streams::ProcessResponses.
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
EventStoreClient::GRPC::Shared::Streams::ProcessResponses.
|
49
|
+
new(config: config).
|
50
|
+
call(
|
51
|
+
response.success,
|
52
|
+
skip_deserialization,
|
53
|
+
skip_decryption
|
54
|
+
)
|
53
55
|
yielder << processed_response if processed_response.success.any?
|
54
56
|
raise StopIteration if end_reached?(response.success, max_count)
|
55
57
|
|
@@ -20,7 +20,7 @@ module EventStoreClient
|
|
20
20
|
yield options if block_given?
|
21
21
|
|
22
22
|
callback = proc do |response|
|
23
|
-
result = Shared::Streams::ProcessResponse.new.call(
|
23
|
+
result = Shared::Streams::ProcessResponse.new(config: config).call(
|
24
24
|
response,
|
25
25
|
skip_deserialization,
|
26
26
|
skip_decryption
|
@@ -41,7 +41,10 @@ module EventStoreClient
|
|
41
41
|
# @param options [Hash]
|
42
42
|
# @return [EventStore::Client::Streams::ReadReq::Options]
|
43
43
|
def normalize_options(stream_name, options)
|
44
|
-
options =
|
44
|
+
options =
|
45
|
+
Options::Streams::ReadOptions.
|
46
|
+
new(stream_name, options, config: config).
|
47
|
+
request_options
|
45
48
|
EventStore::Client::Streams::ReadReq::Options.new(options).tap do |opts|
|
46
49
|
opts.subscription =
|
47
50
|
EventStore::Client::Streams::ReadReq::Options::SubscriptionOptions.new
|
@@ -7,18 +7,7 @@ require 'net/http'
|
|
7
7
|
module EventStoreClient
|
8
8
|
module GRPC
|
9
9
|
class Connection
|
10
|
-
include Configuration
|
11
|
-
include Extensions::OptionsExtension
|
12
|
-
|
13
|
-
option(:host) { Discover.current_member.host }
|
14
|
-
option(:port) { Discover.current_member.port }
|
15
|
-
option(:username) { config.eventstore_url.username }
|
16
|
-
option(:password) { config.eventstore_url.password }
|
17
|
-
option(:timeout) { config.eventstore_url.timeout }
|
18
|
-
|
19
10
|
class << self
|
20
|
-
include Configuration
|
21
|
-
|
22
11
|
# Resolve which connection class we instantiate, based on config.eventstore_url.tls config
|
23
12
|
# option. If :new method is called from SecureConnection or InsecureConnection class - then
|
24
13
|
# that particular class will be instantiated despite on config.eventstore_url.tls config
|
@@ -35,13 +24,14 @@ module EventStoreClient
|
|
35
24
|
# Cluster::InsecureConnection.new
|
36
25
|
# # => #<EventStoreClient::GRPC::Cluster::InsecureConnection>
|
37
26
|
# ```
|
38
|
-
|
27
|
+
# @param config [EventStoreClient::Config]
|
28
|
+
def new(config:, **options)
|
39
29
|
return super unless self == Connection
|
40
30
|
|
41
31
|
if config.eventstore_url.tls
|
42
|
-
Cluster::SecureConnection.new(
|
32
|
+
Cluster::SecureConnection.new(config: config, **options)
|
43
33
|
else
|
44
|
-
Cluster::InsecureConnection.new(
|
34
|
+
Cluster::InsecureConnection.new(config: config, **options)
|
45
35
|
end
|
46
36
|
end
|
47
37
|
|
@@ -52,6 +42,22 @@ module EventStoreClient
|
|
52
42
|
end
|
53
43
|
end
|
54
44
|
|
45
|
+
include Extensions::OptionsExtension
|
46
|
+
|
47
|
+
option(:host) { Discover.current_member(config: config).host }
|
48
|
+
option(:port) { Discover.current_member(config: config).port }
|
49
|
+
option(:username) { config.eventstore_url.username }
|
50
|
+
option(:password) { config.eventstore_url.password }
|
51
|
+
option(:timeout) { config.eventstore_url.timeout }
|
52
|
+
|
53
|
+
attr_reader :config
|
54
|
+
private :config
|
55
|
+
|
56
|
+
def initialize(config:, **options)
|
57
|
+
@config = config
|
58
|
+
super
|
59
|
+
end
|
60
|
+
|
55
61
|
def call(stub_class)
|
56
62
|
raise NotImplementedError
|
57
63
|
end
|
@@ -5,55 +5,75 @@
|
|
5
5
|
module EventStoreClient
|
6
6
|
module GRPC
|
7
7
|
class Discover
|
8
|
-
include Configuration
|
9
|
-
|
10
8
|
class << self
|
9
|
+
# @param config [EventStoreClient::Config]
|
11
10
|
# @return [EventStoreClient::GRPC::Cluster::Member]
|
12
|
-
def current_member
|
13
|
-
@exception = nil
|
14
|
-
return @current_member if member_alive?
|
15
|
-
|
16
|
-
semaphore.synchronize do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
11
|
+
def current_member(config:)
|
12
|
+
@exception[config.name] = nil
|
13
|
+
return @current_member[config.name] if member_alive?(@current_member[config.name])
|
14
|
+
|
15
|
+
semaphore(config.name).synchronize do
|
16
|
+
current_member = @current_member[config.name]
|
17
|
+
raise @exception[config.name] if @exception[config.name]
|
18
|
+
return current_member if member_alive?(current_member)
|
19
|
+
|
20
|
+
failed_member = current_member&.failed_endpoint ? current_member : nil
|
21
|
+
begin
|
22
|
+
@current_member[config.name] = new(config: config).call(failed_member: failed_member)
|
23
|
+
rescue StandardError => e
|
24
|
+
@exception[config.name] = e
|
25
|
+
@current_member[config.name] = nil
|
26
|
+
raise
|
27
|
+
end
|
28
28
|
end
|
29
|
-
raise @exception if @exception
|
30
29
|
|
31
|
-
@current_member
|
30
|
+
@current_member[config.name]
|
32
31
|
end
|
33
32
|
|
33
|
+
# @param member [EventStoreClient::GRPC::Cluster::Member, nil]
|
34
34
|
# @return [Boolean]
|
35
|
-
def member_alive?
|
36
|
-
return false if
|
35
|
+
def member_alive?(member)
|
36
|
+
return false if member&.failed_endpoint
|
37
|
+
|
38
|
+
!member.nil?
|
39
|
+
end
|
37
40
|
|
38
|
-
|
41
|
+
# @return [void]
|
42
|
+
def init_default_discover_vars
|
43
|
+
@exception = {}
|
44
|
+
@current_member = {}
|
45
|
+
@semaphore = {}
|
39
46
|
end
|
40
47
|
|
41
48
|
private
|
42
49
|
|
50
|
+
# @param config_name [String, Symbol]
|
43
51
|
# @return [Thread::Mutex]
|
44
|
-
def semaphore
|
45
|
-
@semaphore ||= Thread::Mutex.new
|
52
|
+
def semaphore(config_name)
|
53
|
+
@semaphore[config_name] ||= Thread::Mutex.new
|
46
54
|
end
|
47
55
|
end
|
48
56
|
|
57
|
+
init_default_discover_vars
|
58
|
+
|
59
|
+
attr_reader :config
|
60
|
+
private :config
|
61
|
+
|
62
|
+
# @param config [EventStoreClient::Config]
|
63
|
+
def initialize(config:)
|
64
|
+
@config = config
|
65
|
+
end
|
66
|
+
|
49
67
|
# @param failed_member [EventStoreClient::GRPC::Cluster::Member, nil]
|
50
68
|
# @return [EventStoreClient::GRPC::Cluster::Member]
|
51
69
|
def call(failed_member: nil)
|
52
70
|
if needs_discover?
|
53
|
-
|
71
|
+
discovery =
|
72
|
+
Cluster::GossipDiscover.new(config: config).call(nodes, failed_member: failed_member)
|
73
|
+
return discovery
|
54
74
|
end
|
55
75
|
|
56
|
-
Cluster::QuerylessDiscover.new.call(config.eventstore_url.nodes.to_a)
|
76
|
+
Cluster::QuerylessDiscover.new(config: config).call(config.eventstore_url.nodes.to_a)
|
57
77
|
end
|
58
78
|
|
59
79
|
private
|
@@ -7,10 +7,8 @@ module EventStoreClient
|
|
7
7
|
module Options
|
8
8
|
module Streams
|
9
9
|
class ReadOptions
|
10
|
-
|
11
|
-
|
12
|
-
attr_reader :options, :stream_name
|
13
|
-
private :options, :stream_name
|
10
|
+
attr_reader :options, :stream_name, :config
|
11
|
+
private :options, :stream_name, :config
|
14
12
|
|
15
13
|
# @param stream_name [String]
|
16
14
|
# @param options [Hash]
|
@@ -39,9 +37,11 @@ module EventStoreClient
|
|
39
37
|
# @option [Hash] :filter see
|
40
38
|
# {EventStoreClient::GRPC::Shared::Options::FilterOptions#initialize} for available
|
41
39
|
# values
|
42
|
-
|
40
|
+
# @param config [EventStoreClient::Config]
|
41
|
+
def initialize(stream_name, options, config:)
|
43
42
|
@stream_name = stream_name
|
44
43
|
@options = options
|
44
|
+
@config = config
|
45
45
|
end
|
46
46
|
|
47
47
|
# @return [Hash] see event_store.client.streams.ReadReq.Options for available options
|
@@ -6,7 +6,14 @@ module EventStoreClient
|
|
6
6
|
module Streams
|
7
7
|
class ProcessResponse
|
8
8
|
include Dry::Monads[:result]
|
9
|
-
|
9
|
+
|
10
|
+
attr_reader :config
|
11
|
+
private :config
|
12
|
+
|
13
|
+
# @param config [EventStoreClient::Config]
|
14
|
+
def initialize(config:)
|
15
|
+
@config = config
|
16
|
+
end
|
10
17
|
|
11
18
|
# @api private
|
12
19
|
# @param response [EventStore::Client::Streams::ReadResp]
|
@@ -6,7 +6,14 @@ module EventStoreClient
|
|
6
6
|
module Streams
|
7
7
|
class ProcessResponses
|
8
8
|
include Dry::Monads[:result]
|
9
|
-
|
9
|
+
|
10
|
+
attr_reader :config
|
11
|
+
private :config
|
12
|
+
|
13
|
+
# @param config [EventStoreClient::Config]
|
14
|
+
def initialize(config:)
|
15
|
+
@config = config
|
16
|
+
end
|
10
17
|
|
11
18
|
# @api private
|
12
19
|
# @param responses [Array<EventStore::Client::Streams::ReadResp>]
|
@@ -13,7 +13,7 @@ module EventStoreClient
|
|
13
13
|
|
14
14
|
option(:eventstore_url) { 'esdb://localhost:2113' }
|
15
15
|
option(:per_page) { 20 }
|
16
|
-
option(:mapper) { Mapper::Default.new }
|
16
|
+
option(:mapper) { Mapper::Default.new(config: self) }
|
17
17
|
option(:default_event_class) { DeserializedEvent }
|
18
18
|
option(:logger)
|
19
19
|
option(:skip_deserialization) { false }
|
@@ -22,6 +22,7 @@ module EventStoreClient
|
|
22
22
|
# of a Stub class of your request. More GRPC options can be found here
|
23
23
|
# https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/grpc_types.h
|
24
24
|
option(:channel_args) # Hash
|
25
|
+
option(:name) { :default }
|
25
26
|
|
26
27
|
def eventstore_url=(value)
|
27
28
|
@eventstore_url =
|
@@ -5,12 +5,14 @@
|
|
5
5
|
module EventStoreClient
|
6
6
|
module Mapper
|
7
7
|
class Default
|
8
|
-
attr_reader :serializer
|
9
|
-
private :serializer
|
8
|
+
attr_reader :serializer, :config
|
9
|
+
private :serializer, :config
|
10
10
|
|
11
|
+
# @param config [EventStoreClient::Config]
|
11
12
|
# @param serializer [#serialize, #deserialize]
|
12
|
-
def initialize(serializer: Serializer::Json)
|
13
|
+
def initialize(config:, serializer: Serializer::Json)
|
13
14
|
@serializer = serializer
|
15
|
+
@config = config
|
14
16
|
end
|
15
17
|
|
16
18
|
# @param event [EventStoreClient::DeserializedEvent]
|
@@ -24,7 +26,9 @@ module EventStoreClient
|
|
24
26
|
def deserialize(event_or_raw_event, **)
|
25
27
|
return event_or_raw_event if event_or_raw_event.is_a?(EventStoreClient::DeserializedEvent)
|
26
28
|
|
27
|
-
Serializer::EventDeserializer.call(
|
29
|
+
Serializer::EventDeserializer.call(
|
30
|
+
event_or_raw_event, config: config, serializer: serializer
|
31
|
+
)
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -8,20 +8,21 @@ require 'event_store_client/data_decryptor'
|
|
8
8
|
|
9
9
|
module EventStoreClient
|
10
10
|
module Mapper
|
11
|
-
##
|
12
11
|
# Transforms given event's data and encrypts/decrypts selected subset of data
|
13
12
|
# based on encryption schema stored in the event itself.
|
14
13
|
class Encrypted
|
15
14
|
MissingEncryptionKey = Class.new(StandardError)
|
16
15
|
|
17
|
-
attr_reader :key_repository, :serializer
|
18
|
-
private :key_repository, :serializer
|
16
|
+
attr_reader :key_repository, :serializer, :config
|
17
|
+
private :key_repository, :serializer, :config
|
19
18
|
|
20
19
|
# @param key_repository [#find, #create, #encrypt, #decrypt]
|
21
20
|
# See spec/support/dummy_repository.rb for the example of simple in-memory implementation
|
21
|
+
# @param config [EventStoreClient::Config]
|
22
22
|
# @param serializer [#serialize, #deserialize]
|
23
|
-
def initialize(key_repository, serializer: Serializer::Json)
|
23
|
+
def initialize(key_repository, config:, serializer: Serializer::Json)
|
24
24
|
@key_repository = key_repository
|
25
|
+
@config = config
|
25
26
|
@serializer = serializer
|
26
27
|
end
|
27
28
|
|
@@ -29,7 +30,7 @@ module EventStoreClient
|
|
29
30
|
# @return [Hash]
|
30
31
|
def serialize(event)
|
31
32
|
# Links don't need to be encrypted
|
32
|
-
return Default.new(serializer: serializer).serialize(event) if event.link?
|
33
|
+
return Default.new(serializer: serializer, config: config).serialize(event) if event.link?
|
33
34
|
|
34
35
|
serialized = Serializer::EventSerializer.call(event, serializer: serializer)
|
35
36
|
encryption_schema =
|
@@ -54,14 +55,16 @@ module EventStoreClient
|
|
54
55
|
# @return event [EventStoreClient::DeserializedEvent]
|
55
56
|
def deserialize(event_or_raw_event, skip_decryption: false)
|
56
57
|
if skip_decryption
|
57
|
-
return Default.new(serializer: serializer).deserialize(event_or_raw_event)
|
58
|
+
return Default.new(serializer: serializer, config: config).deserialize(event_or_raw_event)
|
58
59
|
end
|
59
60
|
|
60
61
|
event =
|
61
62
|
if event_or_raw_event.is_a?(EventStoreClient::DeserializedEvent)
|
62
63
|
event_or_raw_event
|
63
64
|
else
|
64
|
-
Serializer::EventDeserializer.call(
|
65
|
+
Serializer::EventDeserializer.call(
|
66
|
+
event_or_raw_event, config: config, serializer: serializer
|
67
|
+
)
|
65
68
|
end
|
66
69
|
|
67
70
|
decrypted_data =
|
@@ -8,18 +8,20 @@ module EventStoreClient
|
|
8
8
|
class << self
|
9
9
|
# @param raw_event [EventStore::Client::Streams::ReadResp::ReadEvent::RecordedEvent, EventStore::Client::PersistentSubscriptions::ReadResp::ReadEvent::RecordedEvent]
|
10
10
|
# @param serializer [#serialize, #deserialize]
|
11
|
+
# @param config [EventStoreClient::Config]
|
11
12
|
# @return [EventStoreClient::DeserializedEvent]
|
12
|
-
def call(raw_event, serializer: Serializer::Json)
|
13
|
-
new(serializer: serializer).call(raw_event)
|
13
|
+
def call(raw_event, config:, serializer: Serializer::Json)
|
14
|
+
new(config: config, serializer: serializer).call(raw_event)
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
|
-
attr_reader :serializer
|
18
|
-
private :serializer
|
18
|
+
attr_reader :serializer, :config
|
19
|
+
private :serializer, :config
|
19
20
|
|
20
21
|
# @param serializer [#serialize, #deserialize]
|
21
|
-
def initialize(serializer:)
|
22
|
+
def initialize(serializer:, config:)
|
22
23
|
@serializer = serializer
|
24
|
+
@config = config
|
23
25
|
end
|
24
26
|
|
25
27
|
# @param raw_event [EventStore::Client::Streams::ReadResp::ReadEvent::RecordedEvent, EventStore::Client::PersistentSubscriptions::ReadResp::ReadEvent::RecordedEvent]
|
@@ -64,10 +66,6 @@ module EventStoreClient
|
|
64
66
|
|
65
67
|
raw_data
|
66
68
|
end
|
67
|
-
|
68
|
-
def config
|
69
|
-
EventStoreClient.config
|
70
|
-
end
|
71
69
|
end
|
72
70
|
end
|
73
71
|
end
|
data/lib/event_store_client.rb
CHANGED
@@ -16,7 +16,6 @@ require 'event_store_client/connection/url_parser'
|
|
16
16
|
require 'event_store_client/deserialized_event'
|
17
17
|
require 'event_store_client/serialized_event'
|
18
18
|
require 'event_store_client/config'
|
19
|
-
require 'event_store_client/configuration'
|
20
19
|
|
21
20
|
require 'event_store_client/mapper'
|
22
21
|
|
@@ -24,18 +23,44 @@ require 'event_store_client/adapters/grpc'
|
|
24
23
|
|
25
24
|
module EventStoreClient
|
26
25
|
class << self
|
27
|
-
|
28
|
-
|
26
|
+
# @param name [Symbol, String]
|
27
|
+
def configure(name: :default)
|
28
|
+
yield(config(name)) if block_given?
|
29
29
|
end
|
30
30
|
|
31
|
+
# @param name [Symbol, String]
|
31
32
|
# @return [EventStore::Config]
|
32
|
-
def config
|
33
|
-
@config ||= Config.new
|
33
|
+
def config(name = :default)
|
34
|
+
@config[name] ||= Config.new(name: name)
|
34
35
|
end
|
35
36
|
|
37
|
+
# @param config_name [Symbol, String]
|
36
38
|
# @return [EventStore::GRPC::Client]
|
37
|
-
def client
|
38
|
-
GRPC::Client.new
|
39
|
+
def client(config_name: :default)
|
40
|
+
GRPC::Client.new(_config(config_name))
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [void]
|
44
|
+
def init_default_config
|
45
|
+
@config = { default: Config.new }
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# @param config [Symbol, String]
|
51
|
+
# @return [EventStoreClient::Config]
|
52
|
+
# @raise [RuntimeError]
|
53
|
+
def _config(config)
|
54
|
+
return @config[config] if @config[config]
|
55
|
+
|
56
|
+
error_message = <<~TEXT
|
57
|
+
Could not find #{config.inspect} config. You can define it in next way:
|
58
|
+
EventStoreClient.configure(name: #{config.inspect}) do |config|
|
59
|
+
# your config goes here
|
60
|
+
end
|
61
|
+
TEXT
|
62
|
+
raise error_message
|
39
63
|
end
|
40
64
|
end
|
65
|
+
init_default_config
|
41
66
|
end
|
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: 2.
|
4
|
+
version: 2.3.0.pre.beta
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Wilgosz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-12-
|
11
|
+
date: 2022-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-monads
|
@@ -215,7 +215,6 @@ files:
|
|
215
215
|
- lib/event_store_client/adapters/grpc/shared/streams/process_response.rb
|
216
216
|
- lib/event_store_client/adapters/grpc/shared/streams/process_responses.rb
|
217
217
|
- lib/event_store_client/config.rb
|
218
|
-
- lib/event_store_client/configuration.rb
|
219
218
|
- lib/event_store_client/connection/url.rb
|
220
219
|
- lib/event_store_client/connection/url_parser.rb
|
221
220
|
- lib/event_store_client/data_decryptor.rb
|
@@ -248,9 +247,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
248
247
|
version: '0'
|
249
248
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
250
249
|
requirements:
|
251
|
-
- - "
|
250
|
+
- - ">"
|
252
251
|
- !ruby/object:Gem::Version
|
253
|
-
version:
|
252
|
+
version: 1.3.1
|
254
253
|
requirements: []
|
255
254
|
rubygems_version: 3.3.7
|
256
255
|
signing_key:
|