nats-pure 2.3.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +10 -3
- data/lib/nats/client.rb +7 -2
- data/lib/nats/io/client.rb +304 -282
- data/lib/nats/io/errors.rb +2 -0
- data/lib/nats/io/jetstream/api.rb +54 -47
- data/lib/nats/io/jetstream/errors.rb +30 -14
- data/lib/nats/io/jetstream/js/config.rb +9 -3
- data/lib/nats/io/jetstream/js/header.rb +15 -9
- data/lib/nats/io/jetstream/js/status.rb +11 -5
- data/lib/nats/io/jetstream/js/sub.rb +4 -2
- data/lib/nats/io/jetstream/js.rb +10 -8
- data/lib/nats/io/jetstream/manager.rb +104 -83
- data/lib/nats/io/jetstream/msg/ack.rb +15 -9
- data/lib/nats/io/jetstream/msg/ack_methods.rb +24 -22
- data/lib/nats/io/jetstream/msg/metadata.rb +9 -7
- data/lib/nats/io/jetstream/msg.rb +11 -4
- data/lib/nats/io/jetstream/pull_subscription.rb +21 -10
- data/lib/nats/io/jetstream/push_subscription.rb +3 -1
- data/lib/nats/io/jetstream.rb +125 -54
- data/lib/nats/io/kv/api.rb +7 -3
- data/lib/nats/io/kv/bucket_status.rb +7 -5
- data/lib/nats/io/kv/errors.rb +25 -2
- data/lib/nats/io/kv/manager.rb +19 -10
- data/lib/nats/io/kv.rb +359 -22
- data/lib/nats/io/msg.rb +19 -19
- data/lib/nats/io/parser.rb +23 -23
- data/lib/nats/io/rails.rb +2 -0
- data/lib/nats/io/subscription.rb +25 -22
- data/lib/nats/io/version.rb +4 -2
- data/lib/nats/io/websocket.rb +10 -8
- data/lib/nats/nuid.rb +33 -22
- data/lib/nats/service/callbacks.rb +22 -0
- data/lib/nats/service/endpoint.rb +155 -0
- data/lib/nats/service/errors.rb +44 -0
- data/lib/nats/service/group.rb +37 -0
- data/lib/nats/service/monitoring.rb +108 -0
- data/lib/nats/service/stats.rb +52 -0
- data/lib/nats/service/status.rb +66 -0
- data/lib/nats/service/validator.rb +31 -0
- data/lib/nats/service.rb +121 -0
- data/lib/nats/utils/list.rb +26 -0
- data/lib/nats-pure.rb +5 -0
- data/lib/nats.rb +10 -6
- metadata +176 -5
data/lib/nats/io/jetstream.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2021 The NATS Authors
|
2
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
5
|
# you may not use this file except in compliance with the License.
|
@@ -11,17 +13,14 @@
|
|
11
13
|
# See the License for the specific language governing permissions and
|
12
14
|
# limitations under the License.
|
13
15
|
#
|
14
|
-
require_relative
|
15
|
-
require_relative
|
16
|
-
require_relative
|
17
|
-
require_relative
|
18
|
-
require_relative
|
19
|
-
require_relative
|
20
|
-
require_relative
|
21
|
-
require_relative
|
22
|
-
require_relative 'jetstream/msg'
|
23
|
-
require_relative 'jetstream/pull_subscription'
|
24
|
-
require_relative 'jetstream/push_subscription'
|
16
|
+
require_relative "kv"
|
17
|
+
require_relative "jetstream/api"
|
18
|
+
require_relative "jetstream/errors"
|
19
|
+
require_relative "jetstream/js"
|
20
|
+
require_relative "jetstream/manager"
|
21
|
+
require_relative "jetstream/msg"
|
22
|
+
require_relative "jetstream/pull_subscription"
|
23
|
+
require_relative "jetstream/push_subscription"
|
25
24
|
|
26
25
|
module NATS
|
27
26
|
# JetStream returns a context with a similar API as the NATS::Client
|
@@ -33,6 +32,8 @@ module NATS
|
|
33
32
|
# js = nc.jetstream()
|
34
33
|
#
|
35
34
|
class JetStream
|
35
|
+
attr_reader :opts, :prefix, :nc
|
36
|
+
|
36
37
|
# Create a new JetStream context for a NATS connection.
|
37
38
|
#
|
38
39
|
# @param conn [NATS::Client]
|
@@ -40,15 +41,15 @@ module NATS
|
|
40
41
|
# @option params [String] :prefix JetStream API prefix to use for the requests.
|
41
42
|
# @option params [String] :domain JetStream Domain to use for the requests.
|
42
43
|
# @option params [Float] :timeout Default timeout to use for JS requests.
|
43
|
-
def initialize(conn, params={})
|
44
|
+
def initialize(conn, params = {})
|
44
45
|
@nc = conn
|
45
46
|
@prefix = if params[:prefix]
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
params[:prefix]
|
48
|
+
elsif params[:domain]
|
49
|
+
"$JS.#{params[:domain]}.API"
|
50
|
+
else
|
51
|
+
JS::DefaultAPIPrefix
|
52
|
+
end
|
52
53
|
@opts = params
|
53
54
|
@opts[:timeout] ||= 5 # seconds
|
54
55
|
params[:prefix] = @prefix
|
@@ -80,7 +81,7 @@ module NATS
|
|
80
81
|
# @option params [String] :stream Expected Stream to which the message is being published.
|
81
82
|
# @raise [NATS::Timeout] When it takes too long to receive an ack response.
|
82
83
|
# @return [PubAck] The pub ack response.
|
83
|
-
def publish(subject, payload="", **params)
|
84
|
+
def publish(subject, payload = "", **params)
|
84
85
|
params[:timeout] ||= @opts[:timeout]
|
85
86
|
if params[:stream]
|
86
87
|
params[:header] ||= {}
|
@@ -89,8 +90,8 @@ module NATS
|
|
89
90
|
|
90
91
|
# Send message with headers.
|
91
92
|
msg = NATS::Msg.new(subject: subject,
|
92
|
-
|
93
|
-
|
93
|
+
data: payload,
|
94
|
+
header: params[:header])
|
94
95
|
|
95
96
|
begin
|
96
97
|
resp = @nc.request_msg(msg, **params)
|
@@ -105,27 +106,57 @@ module NATS
|
|
105
106
|
|
106
107
|
# subscribe binds or creates a push subscription to a JetStream pull consumer.
|
107
108
|
#
|
108
|
-
# @param subject [String] Subject from which the messages will be fetched.
|
109
|
+
# @param subject [String, Array] Subject(s) from which the messages will be fetched.
|
109
110
|
# @param params [Hash] Options to customize the PushSubscription.
|
110
111
|
# @option params [String] :stream Name of the Stream to which the consumer belongs.
|
111
112
|
# @option params [String] :consumer Name of the Consumer to which the PushSubscription will be bound.
|
113
|
+
# @option params [String] :name Name of the Consumer to which the PushSubscription will be bound.
|
112
114
|
# @option params [String] :durable Consumer durable name from where the messages will be fetched.
|
113
115
|
# @option params [Hash] :config Configuration for the consumer.
|
114
116
|
# @return [NATS::JetStream::PushSubscription]
|
115
|
-
def subscribe(subject, params={}, &cb)
|
117
|
+
def subscribe(subject, params = {}, &cb)
|
116
118
|
params[:consumer] ||= params[:durable]
|
117
|
-
|
119
|
+
params[:consumer] ||= params[:name]
|
120
|
+
multi_filter = if subject.is_a?(Array) && (subject.size == 1)
|
121
|
+
subject = subject.first
|
122
|
+
false
|
123
|
+
elsif subject.is_a?(Array) && (subject.size > 1)
|
124
|
+
true
|
125
|
+
end
|
126
|
+
|
127
|
+
stream = if params[:stream].nil?
|
128
|
+
if multi_filter
|
129
|
+
# Use the first subject to try to find the stream.
|
130
|
+
streams = subject.map do |s|
|
131
|
+
find_stream_name_by_subject(s)
|
132
|
+
rescue NATS::JetStream::Error::NotFound
|
133
|
+
raise NATS::JetStream::Error.new("nats: could not find stream matching filter subject '#{s}'")
|
134
|
+
end
|
135
|
+
|
136
|
+
# Ensure that the filter subjects are not ambiguous.
|
137
|
+
streams.uniq!
|
138
|
+
if streams.count > 1
|
139
|
+
raise NATS::JetStream::Error.new("nats: multiple streams matched filter subjects: #{streams}")
|
140
|
+
end
|
141
|
+
|
142
|
+
streams.first
|
143
|
+
else
|
144
|
+
find_stream_name_by_subject(subject)
|
145
|
+
end
|
146
|
+
else
|
147
|
+
params[:stream]
|
148
|
+
end
|
118
149
|
|
119
150
|
queue = params[:queue]
|
120
151
|
durable = params[:durable]
|
121
|
-
|
152
|
+
params[:flow_control]
|
122
153
|
manual_ack = params[:manual_ack]
|
123
154
|
idle_heartbeat = params[:idle_heartbeat]
|
124
155
|
flow_control = params[:flow_control]
|
125
156
|
config = params[:config]
|
126
157
|
|
127
158
|
if queue
|
128
|
-
if durable
|
159
|
+
if durable && (durable != queue)
|
129
160
|
raise NATS::JetStream::Error.new("nats: cannot create queue subscription '#{queue}' to consumer '#{durable}'")
|
130
161
|
else
|
131
162
|
durable = queue
|
@@ -136,7 +167,7 @@ module NATS
|
|
136
167
|
consumer_found = false
|
137
168
|
should_create = false
|
138
169
|
|
139
|
-
if
|
170
|
+
if !durable
|
140
171
|
should_create = true
|
141
172
|
else
|
142
173
|
begin
|
@@ -151,18 +182,16 @@ module NATS
|
|
151
182
|
end
|
152
183
|
|
153
184
|
if consumer_found
|
154
|
-
if
|
185
|
+
if !config.deliver_group
|
155
186
|
if queue
|
156
187
|
raise NATS::JetStream::Error.new("nats: cannot create a queue subscription for a consumer without a deliver group")
|
157
188
|
elsif cinfo.push_bound
|
158
189
|
raise NATS::JetStream::Error.new("nats: consumer is already bound to a subscription")
|
159
190
|
end
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
raise NATS::JetStream::Error.new("nats: cannot create a queue subscription #{queue} for a consumer with a deliver group #{config.deliver_group}")
|
165
|
-
end
|
191
|
+
elsif !queue
|
192
|
+
raise NATS::JetStream::Error.new("nats: cannot create a subscription for a consumer with a deliver group #{config.deliver_group}")
|
193
|
+
elsif queue != config.deliver_group
|
194
|
+
raise NATS::JetStream::Error.new("nats: cannot create a queue subscription #{queue} for a consumer with a deliver group #{config.deliver_group}")
|
166
195
|
end
|
167
196
|
elsif should_create
|
168
197
|
# Auto-create consumer if none found.
|
@@ -175,21 +204,24 @@ module NATS
|
|
175
204
|
raise NATS::JetStream::Error.new("nats: invalid ConsumerConfig")
|
176
205
|
end
|
177
206
|
|
178
|
-
config.durable_name = durable if
|
179
|
-
config.deliver_group = queue if
|
207
|
+
config.durable_name = durable if !config.durable_name
|
208
|
+
config.deliver_group = queue if !config.deliver_group
|
180
209
|
|
181
210
|
# Create inbox for push consumer.
|
182
211
|
deliver = @nc.new_inbox
|
183
212
|
config.deliver_subject = deliver
|
184
213
|
|
185
214
|
# Auto created consumers use the filter subject.
|
186
|
-
|
215
|
+
if multi_filter
|
216
|
+
config[:filter_subjects] ||= subject
|
217
|
+
else
|
218
|
+
config[:filter_subject] ||= subject
|
219
|
+
end
|
187
220
|
|
188
221
|
# Heartbeats / FlowControl
|
189
222
|
config.flow_control = flow_control
|
190
|
-
if idle_heartbeat
|
223
|
+
if idle_heartbeat || config.idle_heartbeat
|
191
224
|
idle_heartbeat = config.idle_heartbeat if config.idle_heartbeat
|
192
|
-
idle_heartbeat = idle_heartbeat * ::NATS::NANOSECONDS
|
193
225
|
config.idle_heartbeat = idle_heartbeat
|
194
226
|
end
|
195
227
|
|
@@ -199,11 +231,16 @@ module NATS
|
|
199
231
|
end
|
200
232
|
|
201
233
|
# Enable auto acking for async callbacks unless disabled.
|
202
|
-
|
234
|
+
# In case ack policy is none then we also do not require to ack.
|
235
|
+
if cb && !manual_ack && (config.ack_policy != "none")
|
203
236
|
ocb = cb
|
204
237
|
new_cb = proc do |msg|
|
205
238
|
ocb.call(msg)
|
206
|
-
|
239
|
+
begin
|
240
|
+
msg.ack
|
241
|
+
rescue
|
242
|
+
JetStream::Error::MsgAlreadyAckd
|
243
|
+
end
|
207
244
|
end
|
208
245
|
cb = new_cb
|
209
246
|
end
|
@@ -212,42 +249,76 @@ module NATS
|
|
212
249
|
sub.jsi = JS::Sub.new(
|
213
250
|
js: self,
|
214
251
|
stream: stream,
|
215
|
-
consumer: consumer
|
252
|
+
consumer: consumer
|
216
253
|
)
|
217
254
|
sub
|
218
255
|
end
|
219
256
|
|
220
257
|
# pull_subscribe binds or creates a subscription to a JetStream pull consumer.
|
221
258
|
#
|
222
|
-
# @param subject [String] Subject from which the messages will be fetched.
|
259
|
+
# @param subject [String, Array] Subject or subjects from which the messages will be fetched.
|
223
260
|
# @param durable [String] Consumer durable name from where the messages will be fetched.
|
224
261
|
# @param params [Hash] Options to customize the PullSubscription.
|
225
262
|
# @option params [String] :stream Name of the Stream to which the consumer belongs.
|
226
263
|
# @option params [String] :consumer Name of the Consumer to which the PullSubscription will be bound.
|
264
|
+
# @option params [String] :name Name of the Consumer to which the PullSubscription will be bound.
|
227
265
|
# @option params [Hash] :config Configuration for the consumer.
|
228
266
|
# @return [NATS::JetStream::PullSubscription]
|
229
|
-
def pull_subscribe(subject, durable, params={})
|
230
|
-
if durable.empty? && !params[:consumer]
|
267
|
+
def pull_subscribe(subject, durable, params = {})
|
268
|
+
if (!durable || durable.empty?) && !(params[:consumer] || params[:name])
|
231
269
|
raise JetStream::Error::InvalidDurableName.new("nats: invalid durable name")
|
232
270
|
end
|
271
|
+
multi_filter = if subject.is_a?(Array) && (subject.size == 1)
|
272
|
+
subject = subject.first
|
273
|
+
false
|
274
|
+
elsif subject.is_a?(Array) && (subject.size > 1)
|
275
|
+
true
|
276
|
+
end
|
277
|
+
|
233
278
|
params[:consumer] ||= durable
|
234
|
-
|
279
|
+
params[:consumer] ||= params[:name]
|
280
|
+
stream = if params[:stream].nil?
|
281
|
+
if multi_filter
|
282
|
+
# Use the first subject to try to find the stream.
|
283
|
+
streams = subject.map do |s|
|
284
|
+
find_stream_name_by_subject(s)
|
285
|
+
rescue NATS::JetStream::Error::NotFound
|
286
|
+
raise NATS::JetStream::Error.new("nats: could not find stream matching filter subject '#{s}'")
|
287
|
+
end
|
288
|
+
|
289
|
+
# Ensure that the filter subjects are not ambiguous.
|
290
|
+
streams.uniq!
|
291
|
+
if streams.count > 1
|
292
|
+
raise NATS::JetStream::Error.new("nats: multiple streams matched filter subjects: #{streams}")
|
293
|
+
end
|
235
294
|
|
295
|
+
streams.first
|
296
|
+
else
|
297
|
+
find_stream_name_by_subject(subject)
|
298
|
+
end
|
299
|
+
else
|
300
|
+
params[:stream]
|
301
|
+
end
|
236
302
|
begin
|
237
303
|
consumer_info(stream, params[:consumer])
|
238
304
|
rescue NATS::JetStream::Error::NotFound => e
|
239
305
|
# If attempting to bind, then this is a hard error.
|
240
|
-
raise e if params[:stream]
|
306
|
+
raise e if params[:stream] && !multi_filter
|
241
307
|
|
242
|
-
config = if
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
308
|
+
config = if !(params[:config])
|
309
|
+
JetStream::API::ConsumerConfig.new
|
310
|
+
elsif params[:config].is_a?(JetStream::API::ConsumerConfig)
|
311
|
+
params[:config]
|
312
|
+
else
|
313
|
+
JetStream::API::ConsumerConfig.new(params[:config])
|
314
|
+
end
|
249
315
|
config[:durable_name] = durable
|
250
316
|
config[:ack_policy] ||= JS::Config::AckExplicit
|
317
|
+
if multi_filter
|
318
|
+
config[:filter_subjects] ||= subject
|
319
|
+
else
|
320
|
+
config[:filter_subject] ||= subject
|
321
|
+
end
|
251
322
|
add_consumer(stream, config)
|
252
323
|
end
|
253
324
|
|
data/lib/nats/io/kv/api.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2021 The NATS Authors
|
2
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
5
|
# you may not use this file except in compliance with the License.
|
@@ -27,11 +29,13 @@ module NATS
|
|
27
29
|
:placement,
|
28
30
|
:republish,
|
29
31
|
:direct,
|
30
|
-
|
31
|
-
|
32
|
+
:validate_keys,
|
33
|
+
keyword_init: true
|
34
|
+
) do
|
35
|
+
def initialize(opts = {})
|
32
36
|
rem = opts.keys - members
|
33
37
|
opts.delete_if { |k| rem.include?(k) }
|
34
|
-
super
|
38
|
+
super
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2021 The NATS Authors
|
2
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,23 +17,23 @@
|
|
15
17
|
module NATS
|
16
18
|
class KeyValue
|
17
19
|
class BucketStatus
|
18
|
-
attr_reader :bucket
|
20
|
+
attr_reader :bucket, :stream_info
|
19
21
|
|
20
22
|
def initialize(info, bucket)
|
21
|
-
@
|
23
|
+
@stream_info = info
|
22
24
|
@bucket = bucket
|
23
25
|
end
|
24
26
|
|
25
27
|
def values
|
26
|
-
@
|
28
|
+
@stream_info.state.messages
|
27
29
|
end
|
28
30
|
|
29
31
|
def history
|
30
|
-
@
|
32
|
+
@stream_info.config.max_msgs_per_subject
|
31
33
|
end
|
32
34
|
|
33
35
|
def ttl
|
34
|
-
@
|
36
|
+
@stream_info.config.max_age / ::NATS::NANOSECONDS
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
data/lib/nats/io/kv/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2021 The NATS Authors
|
2
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
5
|
# you may not use this file except in compliance with the License.
|
@@ -12,7 +14,7 @@
|
|
12
14
|
# limitations under the License.
|
13
15
|
#
|
14
16
|
|
15
|
-
require_relative
|
17
|
+
require_relative "../errors"
|
16
18
|
|
17
19
|
module NATS
|
18
20
|
class KeyValue
|
@@ -21,7 +23,7 @@ module NATS
|
|
21
23
|
# When a key is not found.
|
22
24
|
class KeyNotFoundError < Error
|
23
25
|
attr_reader :entry, :op
|
24
|
-
def initialize(params={})
|
26
|
+
def initialize(params = {})
|
25
27
|
@entry = params[:entry]
|
26
28
|
@op = params[:op]
|
27
29
|
@message = params[:message]
|
@@ -52,9 +54,30 @@ module NATS
|
|
52
54
|
def initialize(msg)
|
53
55
|
@msg = msg
|
54
56
|
end
|
57
|
+
|
55
58
|
def to_s
|
56
59
|
"nats: #{@msg}"
|
57
60
|
end
|
58
61
|
end
|
62
|
+
|
63
|
+
# When there are no keys.
|
64
|
+
class NoKeysFoundError < Error
|
65
|
+
def to_s
|
66
|
+
"nats: no keys found"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# When history is too large.
|
71
|
+
class KeyHistoryTooLargeError < Error
|
72
|
+
def to_s
|
73
|
+
"nats: history limited to a max of 64"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class InvalidKeyError < Error
|
78
|
+
def to_s
|
79
|
+
"nats: invalid key"
|
80
|
+
end
|
81
|
+
end
|
59
82
|
end
|
60
83
|
end
|
data/lib/nats/io/kv/manager.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2021 The NATS Authors
|
2
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,7 +17,7 @@
|
|
15
17
|
module NATS
|
16
18
|
class KeyValue
|
17
19
|
module Manager
|
18
|
-
def key_value(bucket)
|
20
|
+
def key_value(bucket, params = {})
|
19
21
|
stream = "KV_#{bucket}"
|
20
22
|
begin
|
21
23
|
si = stream_info(stream)
|
@@ -31,16 +33,18 @@ module NATS
|
|
31
33
|
stream: stream,
|
32
34
|
pre: "$KV.#{bucket}.",
|
33
35
|
js: self,
|
34
|
-
direct: si.config.allow_direct
|
36
|
+
direct: si.config.allow_direct,
|
37
|
+
validate_keys: params[:validate_keys]
|
35
38
|
)
|
36
39
|
end
|
37
40
|
|
38
41
|
def create_key_value(config)
|
39
|
-
config = if
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
config = if !config.is_a?(KeyValue::API::KeyValueConfig)
|
43
|
+
config = {bucket: config} if config.is_a?(String)
|
44
|
+
KeyValue::API::KeyValueConfig.new(config)
|
45
|
+
else
|
46
|
+
config
|
47
|
+
end
|
44
48
|
config.history ||= 1
|
45
49
|
config.replicas ||= 1
|
46
50
|
duplicate_window = 2 * 60 # 2 minutes
|
@@ -51,6 +55,10 @@ module NATS
|
|
51
55
|
config.ttl = config.ttl * ::NATS::NANOSECONDS
|
52
56
|
end
|
53
57
|
|
58
|
+
if config.history > 64
|
59
|
+
raise NATS::KeyValue::KeyHistoryTooLargeError
|
60
|
+
end
|
61
|
+
|
54
62
|
stream = JetStream::API::StreamConfig.new(
|
55
63
|
name: "KV_#{config.bucket}",
|
56
64
|
description: config.description,
|
@@ -68,8 +76,8 @@ module NATS
|
|
68
76
|
max_msgs_per_subject: config.history,
|
69
77
|
num_replicas: config.replicas,
|
70
78
|
storage: config.storage,
|
71
|
-
republish: config.republish
|
72
|
-
|
79
|
+
republish: config.republish
|
80
|
+
)
|
73
81
|
|
74
82
|
si = add_stream(stream)
|
75
83
|
KeyValue.new(
|
@@ -77,7 +85,8 @@ module NATS
|
|
77
85
|
stream: stream.name,
|
78
86
|
pre: "$KV.#{config.bucket}.",
|
79
87
|
js: self,
|
80
|
-
direct: si.config.allow_direct
|
88
|
+
direct: si.config.allow_direct,
|
89
|
+
validate_keys: config.validate_keys
|
81
90
|
)
|
82
91
|
end
|
83
92
|
|