event_store_client 2.2.0 → 2.3.0.pre.beta
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 +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:
|