event_store_client 2.2.0 → 2.3.0.pre.beta2
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/docs/configuration.md +47 -0
- data/lib/event_store_client/adapters/grpc/client.rb +21 -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: 5061df902bf2a81601da9b2da7b01b228c24117401c8c86c47f5cb9ba276b92b
|
4
|
+
data.tar.gz: 5fd51e9c6683db7226af8b50545f967060900ae97adad96677b257d3da9e60bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68c779e543067bb2f56e594a31bdf7641947a68d2a937a8c8c9db3a50e65ecb3a619beb1761e021a270147d9b13463f4f252cca12643ee7a30199277ed264007
|
7
|
+
data.tar.gz: 405821db4f1b782e41b797ee89fa5a94c723b5d977d2e9024dbbea226cbb45ac21faeff3c59be90a9723d7b0c61c4b4b7e784bab290513e94370778feaa9a4b5
|
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,12 @@
|
|
5
5
|
module EventStoreClient
|
6
6
|
module GRPC
|
7
7
|
class Client
|
8
|
-
|
8
|
+
attr_reader :config
|
9
|
+
|
10
|
+
# @param config [EventStoreClient::Config]
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
end
|
9
14
|
|
10
15
|
# @param stream_name [String]
|
11
16
|
# @param events_or_event [EventStoreClient::DeserializedEvent, Array<EventStoreClient::DeserializedEvent>]
|
@@ -30,11 +35,11 @@ module EventStoreClient
|
|
30
35
|
# Returns monads' Success/Failure in case whether request was performed.
|
31
36
|
def append_to_stream(stream_name, events_or_event, options: {}, credentials: {}, &blk)
|
32
37
|
if events_or_event.is_a?(Array)
|
33
|
-
Commands::Streams::AppendMultiple.new(**credentials).call(
|
38
|
+
Commands::Streams::AppendMultiple.new(config: config, **credentials).call(
|
34
39
|
stream_name, events_or_event, options: options
|
35
40
|
)
|
36
41
|
else
|
37
|
-
Commands::Streams::Append.new(**credentials).call(
|
42
|
+
Commands::Streams::Append.new(config: config, **credentials).call(
|
38
43
|
stream_name, events_or_event, options: options, &blk
|
39
44
|
)
|
40
45
|
end
|
@@ -91,7 +96,7 @@ module EventStoreClient
|
|
91
96
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
92
97
|
def read(stream_name, options: {}, skip_deserialization: config.skip_deserialization,
|
93
98
|
skip_decryption: config.skip_decryption, credentials: {}, &blk)
|
94
|
-
Commands::Streams::Read.new(**credentials).call(
|
99
|
+
Commands::Streams::Read.new(config: config, **credentials).call(
|
95
100
|
stream_name,
|
96
101
|
options: options,
|
97
102
|
skip_deserialization: skip_deserialization,
|
@@ -106,7 +111,7 @@ module EventStoreClient
|
|
106
111
|
def read_paginated(stream_name, options: {}, credentials: {},
|
107
112
|
skip_deserialization: config.skip_deserialization,
|
108
113
|
skip_decryption: config.skip_decryption, &blk)
|
109
|
-
Commands::Streams::ReadPaginated.new(**credentials).call(
|
114
|
+
Commands::Streams::ReadPaginated.new(config: config, **credentials).call(
|
110
115
|
stream_name,
|
111
116
|
options: options,
|
112
117
|
skip_deserialization: skip_deserialization,
|
@@ -133,7 +138,9 @@ module EventStoreClient
|
|
133
138
|
# ```
|
134
139
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
135
140
|
def hard_delete_stream(stream_name, options: {}, credentials: {}, &blk)
|
136
|
-
Commands::Streams::HardDelete.
|
141
|
+
Commands::Streams::HardDelete.
|
142
|
+
new(config: config, **credentials).
|
143
|
+
call(stream_name, options: options, &blk)
|
137
144
|
end
|
138
145
|
|
139
146
|
# Refs https://developers.eventstore.com/server/v5/streams.html#soft-delete-and-truncatebefore
|
@@ -154,7 +161,9 @@ module EventStoreClient
|
|
154
161
|
# ```
|
155
162
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
156
163
|
def delete_stream(stream_name, options: {}, credentials: {}, &blk)
|
157
|
-
Commands::Streams::Delete.
|
164
|
+
Commands::Streams::Delete.
|
165
|
+
new(config: config, **credentials).
|
166
|
+
call(stream_name, options: options, &blk)
|
158
167
|
end
|
159
168
|
|
160
169
|
# Subscribe to the given stream and listens for events. Note, that it will block execution of
|
@@ -213,7 +222,7 @@ module EventStoreClient
|
|
213
222
|
def subscribe_to_stream(stream_name, handler:, options: {}, credentials: {},
|
214
223
|
skip_deserialization: config.skip_deserialization,
|
215
224
|
skip_decryption: config.skip_decryption, &blk)
|
216
|
-
Commands::Streams::Subscribe.new(**credentials).call(
|
225
|
+
Commands::Streams::Subscribe.new(config: config, **credentials).call(
|
217
226
|
stream_name,
|
218
227
|
handler: handler,
|
219
228
|
options: options,
|
@@ -229,7 +238,7 @@ module EventStoreClient
|
|
229
238
|
def subscribe_to_all(handler:, options: {}, credentials: {},
|
230
239
|
skip_deserialization: config.skip_deserialization,
|
231
240
|
skip_decryption: config.skip_decryption, &blk)
|
232
|
-
Commands::Streams::Subscribe.new(**credentials).call(
|
241
|
+
Commands::Streams::Subscribe.new(config: config, **credentials).call(
|
233
242
|
'$all',
|
234
243
|
handler: handler,
|
235
244
|
options: options,
|
@@ -246,14 +255,14 @@ module EventStoreClient
|
|
246
255
|
# @see #append_to_stream for available params and returned value
|
247
256
|
def link_to(stream_name, events_or_event, options: {}, credentials: {}, &blk)
|
248
257
|
if events_or_event.is_a?(Array)
|
249
|
-
Commands::Streams::LinkToMultiple.new(**credentials).call(
|
258
|
+
Commands::Streams::LinkToMultiple.new(config: config, **credentials).call(
|
250
259
|
stream_name,
|
251
260
|
events_or_event,
|
252
261
|
options: options,
|
253
262
|
&blk
|
254
263
|
)
|
255
264
|
else
|
256
|
-
Commands::Streams::LinkTo.new(**credentials).call(
|
265
|
+
Commands::Streams::LinkTo.new(config: config, **credentials).call(
|
257
266
|
stream_name,
|
258
267
|
events_or_event,
|
259
268
|
options: options,
|
@@ -267,7 +276,7 @@ module EventStoreClient
|
|
267
276
|
# @option credentials [String] :password
|
268
277
|
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
269
278
|
def cluster_info(credentials: {})
|
270
|
-
Commands::Gossip::ClusterInfo.new(**credentials).call
|
279
|
+
Commands::Gossip::ClusterInfo.new(config: config, **credentials).call
|
271
280
|
end
|
272
281
|
end
|
273
282
|
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.beta2
|
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:
|