nats-pure 2.4.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 -3
- data/lib/nats/io/client.rb +303 -280
- data/lib/nats/io/errors.rb +2 -0
- data/lib/nats/io/jetstream/api.rb +53 -50
- 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 +103 -101
- 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 +102 -106
- 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,32 +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
|
-
|
124
|
-
|
125
|
-
keyword_init: true) do
|
126
|
-
def initialize(opts={})
|
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 = {})
|
127
129
|
# Filter unrecognized fields just in case.
|
128
130
|
rem = opts.keys - members
|
129
131
|
opts.delete_if { |k| rem.include?(k) }
|
130
|
-
super
|
132
|
+
super
|
131
133
|
end
|
132
134
|
end
|
133
135
|
|
@@ -196,12 +198,13 @@ module NATS
|
|
196
198
|
:allow_direct,
|
197
199
|
:mirror_direct,
|
198
200
|
:metadata,
|
199
|
-
keyword_init: true
|
200
|
-
|
201
|
+
keyword_init: true
|
202
|
+
) do
|
203
|
+
def initialize(opts = {})
|
201
204
|
# Filter unrecognized fields just in case.
|
202
205
|
rem = opts.keys - members
|
203
206
|
opts.delete_if { |k| rem.include?(k) }
|
204
|
-
super
|
207
|
+
super
|
205
208
|
end
|
206
209
|
end
|
207
210
|
|
@@ -218,8 +221,8 @@ module NATS
|
|
218
221
|
# @!attribute domain
|
219
222
|
# @return [String]
|
220
223
|
StreamInfo = Struct.new(:type, :config, :created, :state, :domain,
|
221
|
-
|
222
|
-
def initialize(opts={})
|
224
|
+
keyword_init: true) do
|
225
|
+
def initialize(opts = {})
|
223
226
|
opts[:config] = StreamConfig.new(opts[:config])
|
224
227
|
opts[:state] = StreamState.new(opts[:state])
|
225
228
|
opts[:created] = ::Time.parse(opts[:created])
|
@@ -227,7 +230,7 @@ module NATS
|
|
227
230
|
# Filter fields and freeze.
|
228
231
|
rem = opts.keys - members
|
229
232
|
opts.delete_if { |k| rem.include?(k) }
|
230
|
-
super
|
233
|
+
super
|
231
234
|
freeze
|
232
235
|
end
|
233
236
|
end
|
@@ -245,12 +248,12 @@ module NATS
|
|
245
248
|
# @!attribute consumer_count
|
246
249
|
# @return [Integer]
|
247
250
|
StreamState = Struct.new(:messages, :bytes, :first_seq, :first_ts,
|
248
|
-
|
249
|
-
|
250
|
-
def initialize(opts={})
|
251
|
+
:last_seq, :last_ts, :consumer_count,
|
252
|
+
keyword_init: true) do
|
253
|
+
def initialize(opts = {})
|
251
254
|
rem = opts.keys - members
|
252
255
|
opts.delete_if { |k| rem.include?(k) }
|
253
|
-
super
|
256
|
+
super
|
254
257
|
end
|
255
258
|
end
|
256
259
|
|
@@ -267,13 +270,13 @@ module NATS
|
|
267
270
|
# @!attribute did_create
|
268
271
|
# @return [Boolean]
|
269
272
|
StreamCreateResponse = Struct.new(:type, :config, :created, :state, :did_create,
|
270
|
-
|
271
|
-
def initialize(opts={})
|
273
|
+
keyword_init: true) do
|
274
|
+
def initialize(opts = {})
|
272
275
|
rem = opts.keys - members
|
273
276
|
opts.delete_if { |k| rem.include?(k) }
|
274
277
|
opts[:config] = StreamConfig.new(opts[:config])
|
275
278
|
opts[:state] = StreamState.new(opts[:state])
|
276
|
-
super
|
279
|
+
super
|
277
280
|
freeze
|
278
281
|
end
|
279
282
|
end
|
@@ -297,11 +300,11 @@ module NATS
|
|
297
300
|
# Filter out members not present.
|
298
301
|
rem = opts.keys - members
|
299
302
|
opts.delete_if { |k| rem.include?(k) }
|
300
|
-
super
|
303
|
+
super
|
301
304
|
end
|
302
305
|
|
303
306
|
def sequence
|
304
|
-
|
307
|
+
seq
|
305
308
|
end
|
306
309
|
end
|
307
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
|