nats-pure 2.3.0 → 2.5.0
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/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/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,9 +14,9 @@
|
|
12
14
|
# limitations under the License.
|
13
15
|
#
|
14
16
|
|
15
|
-
require_relative
|
16
|
-
require
|
17
|
-
require
|
17
|
+
require_relative "errors"
|
18
|
+
require "base64"
|
19
|
+
require "time"
|
18
20
|
|
19
21
|
module NATS
|
20
22
|
class JetStream
|
@@ -29,12 +31,12 @@ module NATS
|
|
29
31
|
# @!attribute stream_seq
|
30
32
|
# @return [Integer] The stream sequence.
|
31
33
|
SequenceInfo = Struct.new(:consumer_seq, :stream_seq, :last_active,
|
32
|
-
|
33
|
-
def initialize(opts={})
|
34
|
+
keyword_init: true) do
|
35
|
+
def initialize(opts = {})
|
34
36
|
# Filter unrecognized fields and freeze.
|
35
37
|
rem = opts.keys - members
|
36
38
|
opts.delete_if { |k| rem.include?(k) }
|
37
|
-
super
|
39
|
+
super
|
38
40
|
freeze
|
39
41
|
end
|
40
42
|
end
|
@@ -64,21 +66,23 @@ module NATS
|
|
64
66
|
# @!attribute cluster
|
65
67
|
# @return [Hash]
|
66
68
|
ConsumerInfo = Struct.new(:type, :stream_name, :name, :created,
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
def initialize(opts={})
|
69
|
+
:config, :delivered, :ack_floor,
|
70
|
+
:num_ack_pending, :num_redelivered, :num_waiting,
|
71
|
+
:num_pending, :cluster, :push_bound,
|
72
|
+
keyword_init: true) do
|
73
|
+
def initialize(opts = {})
|
72
74
|
opts[:created] = Time.parse(opts[:created])
|
73
75
|
opts[:ack_floor] = SequenceInfo.new(opts[:ack_floor])
|
74
76
|
opts[:delivered] = SequenceInfo.new(opts[:delivered])
|
75
77
|
opts[:config][:ack_wait] = opts[:config][:ack_wait] / ::NATS::NANOSECONDS
|
78
|
+
opts[:config][:inactive_threshold] = opts[:config][:inactive_threshold] / ::NATS::NANOSECONDS if opts[:config][:inactive_threshold]
|
79
|
+
opts[:config][:idle_heartbeat] = opts[:config][:idle_heartbeat] / ::NATS::NANOSECONDS if opts[:config][:idle_heartbeat]
|
76
80
|
opts[:config] = ConsumerConfig.new(opts[:config])
|
77
81
|
opts.delete(:cluster)
|
78
82
|
# Filter unrecognized fields just in case.
|
79
83
|
rem = opts.keys - members
|
80
84
|
opts.delete_if { |k| rem.include?(k) }
|
81
|
-
super
|
85
|
+
super
|
82
86
|
freeze
|
83
87
|
end
|
84
88
|
end
|
@@ -102,29 +106,30 @@ module NATS
|
|
102
106
|
# @!attribute max_ack_pending
|
103
107
|
# @return [Integer]
|
104
108
|
ConsumerConfig = Struct.new(:name, :durable_name, :description,
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
109
|
+
:deliver_policy, :opt_start_seq, :opt_start_time,
|
110
|
+
:ack_policy, :ack_wait, :max_deliver, :backoff,
|
111
|
+
:filter_subject, :replay_policy, :rate_limit_bps,
|
112
|
+
:sample_freq, :max_waiting, :max_ack_pending,
|
113
|
+
:flow_control, :idle_heartbeat, :headers_only,
|
114
|
+
# Pull based options
|
115
|
+
:max_batch, :max_expires,
|
116
|
+
# Push based consumers
|
117
|
+
:deliver_subject, :deliver_group,
|
118
|
+
# Ephemeral inactivity threshold
|
119
|
+
:inactive_threshold,
|
120
|
+
# Generally inherited by parent stream and other markers,
|
121
|
+
# now can be configured directly.
|
122
|
+
:num_replicas,
|
123
|
+
# Force memory storage
|
124
|
+
:mem_storage,
|
125
|
+
# NATS v2.10 features
|
126
|
+
:metadata, :filter_subjects, :max_bytes,
|
127
|
+
keyword_init: true) do
|
128
|
+
def initialize(opts = {})
|
124
129
|
# Filter unrecognized fields just in case.
|
125
130
|
rem = opts.keys - members
|
126
131
|
opts.delete_if { |k| rem.include?(k) }
|
127
|
-
super
|
132
|
+
super
|
128
133
|
end
|
129
134
|
end
|
130
135
|
|
@@ -192,12 +197,14 @@ module NATS
|
|
192
197
|
:republish,
|
193
198
|
:allow_direct,
|
194
199
|
:mirror_direct,
|
195
|
-
|
196
|
-
|
200
|
+
:metadata,
|
201
|
+
keyword_init: true
|
202
|
+
) do
|
203
|
+
def initialize(opts = {})
|
197
204
|
# Filter unrecognized fields just in case.
|
198
205
|
rem = opts.keys - members
|
199
206
|
opts.delete_if { |k| rem.include?(k) }
|
200
|
-
super
|
207
|
+
super
|
201
208
|
end
|
202
209
|
end
|
203
210
|
|
@@ -214,8 +221,8 @@ module NATS
|
|
214
221
|
# @!attribute domain
|
215
222
|
# @return [String]
|
216
223
|
StreamInfo = Struct.new(:type, :config, :created, :state, :domain,
|
217
|
-
|
218
|
-
def initialize(opts={})
|
224
|
+
keyword_init: true) do
|
225
|
+
def initialize(opts = {})
|
219
226
|
opts[:config] = StreamConfig.new(opts[:config])
|
220
227
|
opts[:state] = StreamState.new(opts[:state])
|
221
228
|
opts[:created] = ::Time.parse(opts[:created])
|
@@ -223,7 +230,7 @@ module NATS
|
|
223
230
|
# Filter fields and freeze.
|
224
231
|
rem = opts.keys - members
|
225
232
|
opts.delete_if { |k| rem.include?(k) }
|
226
|
-
super
|
233
|
+
super
|
227
234
|
freeze
|
228
235
|
end
|
229
236
|
end
|
@@ -241,12 +248,12 @@ module NATS
|
|
241
248
|
# @!attribute consumer_count
|
242
249
|
# @return [Integer]
|
243
250
|
StreamState = Struct.new(:messages, :bytes, :first_seq, :first_ts,
|
244
|
-
|
245
|
-
|
246
|
-
def initialize(opts={})
|
251
|
+
:last_seq, :last_ts, :consumer_count,
|
252
|
+
keyword_init: true) do
|
253
|
+
def initialize(opts = {})
|
247
254
|
rem = opts.keys - members
|
248
255
|
opts.delete_if { |k| rem.include?(k) }
|
249
|
-
super
|
256
|
+
super
|
250
257
|
end
|
251
258
|
end
|
252
259
|
|
@@ -263,13 +270,13 @@ module NATS
|
|
263
270
|
# @!attribute did_create
|
264
271
|
# @return [Boolean]
|
265
272
|
StreamCreateResponse = Struct.new(:type, :config, :created, :state, :did_create,
|
266
|
-
|
267
|
-
def initialize(opts={})
|
273
|
+
keyword_init: true) do
|
274
|
+
def initialize(opts = {})
|
268
275
|
rem = opts.keys - members
|
269
276
|
opts.delete_if { |k| rem.include?(k) }
|
270
277
|
opts[:config] = StreamConfig.new(opts[:config])
|
271
278
|
opts[:state] = StreamState.new(opts[:state])
|
272
|
-
super
|
279
|
+
super
|
273
280
|
freeze
|
274
281
|
end
|
275
282
|
end
|
@@ -293,11 +300,11 @@ module NATS
|
|
293
300
|
# Filter out members not present.
|
294
301
|
rem = opts.keys - members
|
295
302
|
opts.delete_if { |k| rem.include?(k) }
|
296
|
-
super
|
303
|
+
super
|
297
304
|
end
|
298
305
|
|
299
306
|
def sequence
|
300
|
-
|
307
|
+
seq
|
301
308
|
end
|
302
309
|
end
|
303
310
|
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.
|
@@ -16,7 +18,6 @@ module NATS
|
|
16
18
|
class JetStream
|
17
19
|
# Error is any error that may arise when interacting with JetStream.
|
18
20
|
class Error < NATS::IO::Error
|
19
|
-
|
20
21
|
# When there is a NATS::IO::NoResponders error after making a publish request.
|
21
22
|
class NoStreamResponse < Error; end
|
22
23
|
|
@@ -41,18 +42,25 @@ module NATS
|
|
41
42
|
|
42
43
|
# When the server responds with an error from the JetStream API.
|
43
44
|
class APIError < Error
|
44
|
-
|
45
|
+
attr_accessor :code, :err_code, :description, :stream, :consumer, :seq
|
45
46
|
|
46
|
-
def initialize(params={})
|
47
|
+
def initialize(params = {})
|
47
48
|
@code = params[:code]
|
48
49
|
@err_code = params[:err_code]
|
49
50
|
@description = params[:description]
|
50
51
|
@stream = params[:stream]
|
52
|
+
@consumer = params[:consumer]
|
51
53
|
@seq = params[:seq]
|
52
54
|
end
|
53
55
|
|
54
56
|
def to_s
|
55
|
-
|
57
|
+
if @stream && @consumer
|
58
|
+
"#{@description} (status_code=#{@code}, err_code=#{@err_code}, stream=#{@stream}, consumer=#{@consumer})"
|
59
|
+
elsif @stream
|
60
|
+
"#{@description} (status_code=#{@code}, err_code=#{@err_code}, stream=#{@stream})"
|
61
|
+
else
|
62
|
+
"#{@description} (status_code=#{@code}, err_code=#{@err_code})"
|
63
|
+
end
|
56
64
|
end
|
57
65
|
end
|
58
66
|
|
@@ -61,8 +69,8 @@ module NATS
|
|
61
69
|
# running in cluster mode.
|
62
70
|
# This condition is represented with a message that has 503 status code header.
|
63
71
|
class ServiceUnavailable < APIError
|
64
|
-
def initialize(params={})
|
65
|
-
super
|
72
|
+
def initialize(params = {})
|
73
|
+
super
|
66
74
|
@code ||= 503
|
67
75
|
end
|
68
76
|
end
|
@@ -70,8 +78,8 @@ module NATS
|
|
70
78
|
# When there is a hard failure in the JetStream.
|
71
79
|
# This condition is represented with a message that has 500 status code header.
|
72
80
|
class ServerError < APIError
|
73
|
-
def initialize(params={})
|
74
|
-
super
|
81
|
+
def initialize(params = {})
|
82
|
+
super
|
75
83
|
@code ||= 500
|
76
84
|
end
|
77
85
|
end
|
@@ -79,23 +87,31 @@ module NATS
|
|
79
87
|
# When a JetStream object was not found.
|
80
88
|
# This condition is represented with a message that has 404 status code header.
|
81
89
|
class NotFound < APIError
|
82
|
-
def initialize(params={})
|
83
|
-
super
|
90
|
+
def initialize(params = {})
|
91
|
+
super
|
84
92
|
@code ||= 404
|
85
93
|
end
|
86
94
|
end
|
87
95
|
|
88
96
|
# When the stream is not found.
|
89
|
-
class StreamNotFound < NotFound
|
97
|
+
class StreamNotFound < NotFound
|
98
|
+
def initialize(params = {})
|
99
|
+
super
|
100
|
+
end
|
101
|
+
end
|
90
102
|
|
91
103
|
# When the consumer or durable is not found by name.
|
92
|
-
class ConsumerNotFound < NotFound
|
104
|
+
class ConsumerNotFound < NotFound
|
105
|
+
def initialize(params = {})
|
106
|
+
super
|
107
|
+
end
|
108
|
+
end
|
93
109
|
|
94
110
|
# When the JetStream client makes an invalid request.
|
95
111
|
# This condition is represented with a message that has 400 status code header.
|
96
112
|
class BadRequest < APIError
|
97
|
-
def initialize(params={})
|
98
|
-
super
|
113
|
+
def initialize(params = {})
|
114
|
+
super
|
99
115
|
@code ||= 400
|
100
116
|
end
|
101
117
|
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.
|
@@ -16,10 +18,14 @@ module NATS
|
|
16
18
|
class JetStream
|
17
19
|
module JS
|
18
20
|
module Config
|
21
|
+
# rubocop:disable Naming/ConstantName
|
22
|
+
|
19
23
|
# AckPolicy
|
20
|
-
AckExplicit =
|
21
|
-
AckAll
|
22
|
-
AckNone
|
24
|
+
AckExplicit = "explicit"
|
25
|
+
AckAll = "all"
|
26
|
+
AckNone = "none"
|
27
|
+
|
28
|
+
# rubocop:enable Naming/ConstantName
|
23
29
|
end
|
24
30
|
end
|
25
31
|
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.
|
@@ -16,15 +18,19 @@ module NATS
|
|
16
18
|
class JetStream
|
17
19
|
module JS
|
18
20
|
module Header
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
# rubocop:disable Naming/ConstantName
|
22
|
+
|
23
|
+
Status = "Status"
|
24
|
+
Desc = "Description"
|
25
|
+
MsgID = "Nats-Msg-Id"
|
26
|
+
ExpectedStream = "Nats-Expected-Stream"
|
27
|
+
ExpectedLastSeq = "Nats-Expected-Last-Sequence"
|
28
|
+
ExpectedLastSubjSeq = "Nats-Expected-Last-Subject-Sequence"
|
29
|
+
ExpectedLastMsgID = "Nats-Expected-Last-Msg-Id"
|
30
|
+
LastConsumerSeq = "Nats-Last-Consumer"
|
31
|
+
LastStreamSeq = "Nats-Last-Stream"
|
32
|
+
|
33
|
+
# rubocop:enable Naming/ConstantName
|
28
34
|
end
|
29
35
|
end
|
30
36
|
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.
|
@@ -16,11 +18,15 @@ module NATS
|
|
16
18
|
class JetStream
|
17
19
|
module JS
|
18
20
|
module Status
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
# rubocop:disable Naming/ConstantName
|
22
|
+
|
23
|
+
CtrlMsg = "100"
|
24
|
+
NoMsgs = "404"
|
25
|
+
NotFound = "404"
|
26
|
+
RequestTimeout = "408"
|
27
|
+
ServiceUnavailable = "503"
|
28
|
+
|
29
|
+
# rubocop:enable Naming/ConstantName
|
24
30
|
end
|
25
31
|
end
|
26
32
|
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.
|
@@ -16,9 +18,9 @@ module NATS
|
|
16
18
|
class JetStream
|
17
19
|
module JS
|
18
20
|
class Sub
|
19
|
-
|
21
|
+
attr_accessor :js, :stream, :consumer, :nms
|
20
22
|
|
21
|
-
def initialize(opts={})
|
23
|
+
def initialize(opts = {})
|
22
24
|
@js = opts[:js]
|
23
25
|
@stream = opts[:stream]
|
24
26
|
@consumer = opts[:consumer]
|
data/lib/nats/io/jetstream/js.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,17 +14,17 @@
|
|
12
14
|
# limitations under the License.
|
13
15
|
#
|
14
16
|
|
15
|
-
require_relative
|
16
|
-
require_relative
|
17
|
-
require_relative
|
18
|
-
require_relative
|
17
|
+
require_relative "js/config"
|
18
|
+
require_relative "js/header"
|
19
|
+
require_relative "js/status"
|
20
|
+
require_relative "js/sub"
|
19
21
|
|
20
22
|
module NATS
|
21
23
|
class JetStream
|
22
24
|
# Misc internal functions to support JS API.
|
23
25
|
# @private
|
24
26
|
module JS
|
25
|
-
DefaultAPIPrefix =
|
27
|
+
DefaultAPIPrefix = "$JS.API" # rubocop:disable Naming/ConstantName
|
26
28
|
|
27
29
|
class << self
|
28
30
|
def next_req_to_json(next_req)
|
@@ -34,14 +36,14 @@ module NATS
|
|
34
36
|
end
|
35
37
|
|
36
38
|
def is_status_msg(msg)
|
37
|
-
|
39
|
+
(!msg.nil? and (!msg.header.nil? and msg.header[Header::Status]))
|
38
40
|
end
|
39
41
|
|
40
42
|
# check_503_error raises exception when a NATS::Msg has a 503 status header.
|
41
43
|
# @param msg [NATS::Msg] The message with status headers.
|
42
44
|
# @raise [NATS::JetStream::Error::ServiceUnavailable]
|
43
45
|
def check_503_error(msg)
|
44
|
-
return if msg.nil?
|
46
|
+
return if msg.nil? || msg.header.nil?
|
45
47
|
if msg.header[Header::Status] == Status::ServiceUnavailable
|
46
48
|
raise ::NATS::JetStream::Error::ServiceUnavailable
|
47
49
|
end
|
@@ -59,7 +61,7 @@ module NATS
|
|
59
61
|
check_503_error(msg)
|
60
62
|
code = msg.header[JS::Header::Status]
|
61
63
|
desc = msg.header[JS::Header::Desc]
|
62
|
-
|
64
|
+
::NATS::JetStream::API::Error.new({code: code, description: desc})
|
63
65
|
end
|
64
66
|
|
65
67
|
# from_error takes an API response that errored and maps the error
|