nats-pure 2.2.0 → 2.2.1
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/lib/nats/io/client.rb +11 -7
- data/lib/nats/io/jetstream/api.rb +305 -0
- data/lib/nats/io/jetstream/errors.rb +104 -0
- data/lib/nats/io/jetstream/js/config.rb +26 -0
- data/lib/nats/io/jetstream/js/header.rb +31 -0
- data/lib/nats/io/jetstream/js/status.rb +27 -0
- data/lib/nats/io/jetstream/js/sub.rb +30 -0
- data/lib/nats/io/jetstream/js.rb +93 -0
- data/lib/nats/io/jetstream/manager.rb +284 -0
- data/lib/nats/io/jetstream/msg/ack.rb +57 -0
- data/lib/nats/io/jetstream/msg/ack_methods.rb +107 -0
- data/lib/nats/io/jetstream/msg/metadata.rb +37 -0
- data/lib/nats/io/jetstream/msg.rb +26 -0
- data/lib/nats/io/jetstream/pull_subscription.rb +260 -0
- data/lib/nats/io/jetstream/push_subscription.rb +42 -0
- data/lib/nats/io/jetstream.rb +269 -0
- data/lib/nats/io/kv/api.rb +39 -0
- data/lib/nats/io/kv/bucket_status.rb +38 -0
- data/lib/nats/io/kv/errors.rb +60 -0
- data/lib/nats/io/kv/manager.rb +89 -0
- data/lib/nats/io/kv.rb +5 -157
- data/lib/nats/io/msg.rb +1 -1
- data/lib/nats/io/version.rb +1 -1
- metadata +21 -3
- data/lib/nats/io/js.rb +0 -1434
@@ -0,0 +1,284 @@
|
|
1
|
+
# Copyright 2021 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module NATS
|
16
|
+
class JetStream
|
17
|
+
# A JetStream::Manager can be used to make requests to the JetStream API.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# require 'nats/client'
|
21
|
+
#
|
22
|
+
# nc = NATS.connect("demo.nats.io")
|
23
|
+
#
|
24
|
+
# config = JetStream::API::StreamConfig.new()
|
25
|
+
# nc.jsm.add_stream(config)
|
26
|
+
#
|
27
|
+
#
|
28
|
+
module Manager
|
29
|
+
# add_stream creates a stream with a given config.
|
30
|
+
# @param config [JetStream::API::StreamConfig] Configuration of the stream to create.
|
31
|
+
# @param params [Hash] Options to customize API request.
|
32
|
+
# @option params [Float] :timeout Time to wait for response.
|
33
|
+
# @return [JetStream::API::StreamCreateResponse] The result of creating a Stream.
|
34
|
+
def add_stream(config, params={})
|
35
|
+
config = if not config.is_a?(JetStream::API::StreamConfig)
|
36
|
+
JetStream::API::StreamConfig.new(config)
|
37
|
+
else
|
38
|
+
config
|
39
|
+
end
|
40
|
+
stream = config[:name]
|
41
|
+
raise ArgumentError.new(":name is required to create streams") unless stream
|
42
|
+
raise ArgumentError.new("Spaces, tabs, period (.), greater than (>) or asterisk (*) are prohibited in stream names") if stream =~ /(\s|\.|\>|\*)/
|
43
|
+
req_subject = "#{@prefix}.STREAM.CREATE.#{stream}"
|
44
|
+
|
45
|
+
cfg = config.to_h.compact
|
46
|
+
result = api_request(req_subject, cfg.to_json, params)
|
47
|
+
JetStream::API::StreamCreateResponse.new(result)
|
48
|
+
end
|
49
|
+
|
50
|
+
# stream_info retrieves the current status of a stream.
|
51
|
+
# @param stream [String] Name of the stream.
|
52
|
+
# @param params [Hash] Options to customize API request.
|
53
|
+
# @option params [Float] :timeout Time to wait for response.
|
54
|
+
# @return [JetStream::API::StreamInfo] The latest StreamInfo of the stream.
|
55
|
+
def stream_info(stream, params={})
|
56
|
+
raise JetStream::Error::InvalidStreamName.new("nats: invalid stream name") if stream.nil? or stream.empty?
|
57
|
+
|
58
|
+
req_subject = "#{@prefix}.STREAM.INFO.#{stream}"
|
59
|
+
result = api_request(req_subject, '', params)
|
60
|
+
JetStream::API::StreamInfo.new(result)
|
61
|
+
end
|
62
|
+
|
63
|
+
# update_stream edits an existed stream with a given config.
|
64
|
+
# @param config [JetStream::API::StreamConfig] Configuration of the stream to create.
|
65
|
+
# @param params [Hash] Options to customize API request.
|
66
|
+
# @option params [Float] :timeout Time to wait for response.
|
67
|
+
# @return [JetStream::API::StreamCreateResponse] The result of creating a Stream.
|
68
|
+
def update_stream(config, params={})
|
69
|
+
config = if not config.is_a?(JetStream::API::StreamConfig)
|
70
|
+
JetStream::API::StreamConfig.new(config)
|
71
|
+
else
|
72
|
+
config
|
73
|
+
end
|
74
|
+
stream = config[:name]
|
75
|
+
raise ArgumentError.new(":name is required to create streams") unless stream
|
76
|
+
raise ArgumentError.new("Spaces, tabs, period (.), greater than (>) or asterisk (*) are prohibited in stream names") if stream =~ /(\s|\.|\>|\*)/
|
77
|
+
req_subject = "#{@prefix}.STREAM.UPDATE.#{stream}"
|
78
|
+
cfg = config.to_h.compact
|
79
|
+
result = api_request(req_subject, cfg.to_json, params)
|
80
|
+
JetStream::API::StreamCreateResponse.new(result)
|
81
|
+
end
|
82
|
+
|
83
|
+
# delete_stream deletes a stream.
|
84
|
+
# @param stream [String] Name of the stream.
|
85
|
+
# @param params [Hash] Options to customize API request.
|
86
|
+
# @option params [Float] :timeout Time to wait for response.
|
87
|
+
# @return [Boolean]
|
88
|
+
def delete_stream(stream, params={})
|
89
|
+
raise JetStream::Error::InvalidStreamName.new("nats: invalid stream name") if stream.nil? or stream.empty?
|
90
|
+
|
91
|
+
req_subject = "#{@prefix}.STREAM.DELETE.#{stream}"
|
92
|
+
result = api_request(req_subject, '', params)
|
93
|
+
result[:success]
|
94
|
+
end
|
95
|
+
|
96
|
+
# add_consumer creates a consumer with a given config.
|
97
|
+
# @param stream [String] Name of the stream.
|
98
|
+
# @param config [JetStream::API::ConsumerConfig] Configuration of the consumer to create.
|
99
|
+
# @param params [Hash] Options to customize API request.
|
100
|
+
# @option params [Float] :timeout Time to wait for response.
|
101
|
+
# @return [JetStream::API::ConsumerInfo] The result of creating a Consumer.
|
102
|
+
def add_consumer(stream, config, params={})
|
103
|
+
raise JetStream::Error::InvalidStreamName.new("nats: invalid stream name") if stream.nil? or stream.empty?
|
104
|
+
config = if not config.is_a?(JetStream::API::ConsumerConfig)
|
105
|
+
JetStream::API::ConsumerConfig.new(config)
|
106
|
+
else
|
107
|
+
config
|
108
|
+
end
|
109
|
+
|
110
|
+
req_subject = case
|
111
|
+
when config[:name]
|
112
|
+
# NOTE: Only supported after nats-server v2.9.0
|
113
|
+
if config[:filter_subject] && config[:filter_subject] != ">"
|
114
|
+
"#{@prefix}.CONSUMER.CREATE.#{stream}.#{config[:name]}.#{config[:filter_subject]}"
|
115
|
+
else
|
116
|
+
"#{@prefix}.CONSUMER.CREATE.#{stream}.#{config[:name]}"
|
117
|
+
end
|
118
|
+
when config[:durable_name]
|
119
|
+
"#{@prefix}.CONSUMER.DURABLE.CREATE.#{stream}.#{config[:durable_name]}"
|
120
|
+
else
|
121
|
+
"#{@prefix}.CONSUMER.CREATE.#{stream}"
|
122
|
+
end
|
123
|
+
|
124
|
+
config[:ack_policy] ||= JS::Config::AckExplicit
|
125
|
+
# Check if have to normalize ack wait so that it is in nanoseconds for Go compat.
|
126
|
+
if config[:ack_wait]
|
127
|
+
raise ArgumentError.new("nats: invalid ack wait") unless config[:ack_wait].is_a?(Integer)
|
128
|
+
config[:ack_wait] = config[:ack_wait] * ::NATS::NANOSECONDS
|
129
|
+
end
|
130
|
+
if config[:inactive_threshold]
|
131
|
+
raise ArgumentError.new("nats: invalid inactive threshold") unless config[:inactive_threshold].is_a?(Integer)
|
132
|
+
config[:inactive_threshold] = config[:inactive_threshold] * ::NATS::NANOSECONDS
|
133
|
+
end
|
134
|
+
|
135
|
+
cfg = config.to_h.compact
|
136
|
+
req = {
|
137
|
+
stream_name: stream,
|
138
|
+
config: cfg
|
139
|
+
}
|
140
|
+
|
141
|
+
result = api_request(req_subject, req.to_json, params)
|
142
|
+
JetStream::API::ConsumerInfo.new(result).freeze
|
143
|
+
end
|
144
|
+
|
145
|
+
# consumer_info retrieves the current status of a consumer.
|
146
|
+
# @param stream [String] Name of the stream.
|
147
|
+
# @param consumer [String] Name of the consumer.
|
148
|
+
# @param params [Hash] Options to customize API request.
|
149
|
+
# @option params [Float] :timeout Time to wait for response.
|
150
|
+
# @return [JetStream::API::ConsumerInfo] The latest ConsumerInfo of the consumer.
|
151
|
+
def consumer_info(stream, consumer, params={})
|
152
|
+
raise JetStream::Error::InvalidStreamName.new("nats: invalid stream name") if stream.nil? or stream.empty?
|
153
|
+
raise JetStream::Error::InvalidConsumerName.new("nats: invalid consumer name") if consumer.nil? or consumer.empty?
|
154
|
+
|
155
|
+
req_subject = "#{@prefix}.CONSUMER.INFO.#{stream}.#{consumer}"
|
156
|
+
result = api_request(req_subject, '', params)
|
157
|
+
JetStream::API::ConsumerInfo.new(result)
|
158
|
+
end
|
159
|
+
|
160
|
+
# delete_consumer deletes a consumer.
|
161
|
+
# @param stream [String] Name of the stream.
|
162
|
+
# @param consumer [String] Name of the consumer.
|
163
|
+
# @param params [Hash] Options to customize API request.
|
164
|
+
# @option params [Float] :timeout Time to wait for response.
|
165
|
+
# @return [Boolean]
|
166
|
+
def delete_consumer(stream, consumer, params={})
|
167
|
+
raise JetStream::Error::InvalidStreamName.new("nats: invalid stream name") if stream.nil? or stream.empty?
|
168
|
+
raise JetStream::Error::InvalidConsumerName.new("nats: invalid consumer name") if consumer.nil? or consumer.empty?
|
169
|
+
|
170
|
+
req_subject = "#{@prefix}.CONSUMER.DELETE.#{stream}.#{consumer}"
|
171
|
+
result = api_request(req_subject, '', params)
|
172
|
+
result[:success]
|
173
|
+
end
|
174
|
+
|
175
|
+
# find_stream_name_by_subject does a lookup for the stream to which
|
176
|
+
# the subject belongs.
|
177
|
+
# @param subject [String] The subject that belongs to a stream.
|
178
|
+
# @param params [Hash] Options to customize API request.
|
179
|
+
# @option params [Float] :timeout Time to wait for response.
|
180
|
+
# @return [String] The name of the JetStream stream for the subject.
|
181
|
+
def find_stream_name_by_subject(subject, params={})
|
182
|
+
req_subject = "#{@prefix}.STREAM.NAMES"
|
183
|
+
req = { subject: subject }
|
184
|
+
result = api_request(req_subject, req.to_json, params)
|
185
|
+
raise JetStream::Error::NotFound unless result[:streams]
|
186
|
+
|
187
|
+
result[:streams].first
|
188
|
+
end
|
189
|
+
|
190
|
+
# get_msg retrieves a message from the stream.
|
191
|
+
# @param stream_name [String] The stream_name.
|
192
|
+
# @param params [Hash] Options to customize API request.
|
193
|
+
# @option next [Boolean] Fetch the next message for a subject.
|
194
|
+
# @option seq [Integer] Sequence number of a message.
|
195
|
+
# @option subject [String] Subject of the message.
|
196
|
+
# @option direct [Boolean] Use direct mode to for faster access (requires NATS v2.9.0)
|
197
|
+
def get_msg(stream_name, params={})
|
198
|
+
req = {}
|
199
|
+
case
|
200
|
+
when params[:next]
|
201
|
+
req[:seq] = params[:seq]
|
202
|
+
req[:next_by_subj] = params[:subject]
|
203
|
+
when params[:seq]
|
204
|
+
req[:seq] = params[:seq]
|
205
|
+
when params[:subject]
|
206
|
+
req[:last_by_subj] = params[:subject]
|
207
|
+
end
|
208
|
+
|
209
|
+
data = req.to_json
|
210
|
+
if params[:direct]
|
211
|
+
if params[:subject] and not params[:seq]
|
212
|
+
# last_by_subject type request requires no payload.
|
213
|
+
data = ''
|
214
|
+
req_subject = "#{@prefix}.DIRECT.GET.#{stream_name}.#{params[:subject]}"
|
215
|
+
else
|
216
|
+
req_subject = "#{@prefix}.DIRECT.GET.#{stream_name}"
|
217
|
+
end
|
218
|
+
else
|
219
|
+
req_subject = "#{@prefix}.STREAM.MSG.GET.#{stream_name}"
|
220
|
+
end
|
221
|
+
resp = api_request(req_subject, data, direct: params[:direct])
|
222
|
+
msg = if params[:direct]
|
223
|
+
_lift_msg_to_raw_msg(resp)
|
224
|
+
else
|
225
|
+
JetStream::API::RawStreamMsg.new(resp[:message])
|
226
|
+
end
|
227
|
+
|
228
|
+
msg
|
229
|
+
end
|
230
|
+
|
231
|
+
def get_last_msg(stream_name, subject, params={})
|
232
|
+
params[:subject] = subject
|
233
|
+
get_msg(stream_name, params)
|
234
|
+
end
|
235
|
+
|
236
|
+
def account_info
|
237
|
+
api_request("#{@prefix}.INFO")
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
def api_request(req_subject, req="", params={})
|
243
|
+
params[:timeout] ||= @opts[:timeout]
|
244
|
+
msg = begin
|
245
|
+
@nc.request(req_subject, req, **params)
|
246
|
+
rescue NATS::IO::NoRespondersError
|
247
|
+
raise JetStream::Error::ServiceUnavailable
|
248
|
+
end
|
249
|
+
|
250
|
+
result = if params[:direct]
|
251
|
+
msg
|
252
|
+
else
|
253
|
+
JSON.parse(msg.data, symbolize_names: true)
|
254
|
+
end
|
255
|
+
if result.is_a?(Hash) and result[:error]
|
256
|
+
raise JS.from_error(result[:error])
|
257
|
+
end
|
258
|
+
|
259
|
+
result
|
260
|
+
end
|
261
|
+
|
262
|
+
def _lift_msg_to_raw_msg(msg)
|
263
|
+
if msg.header and msg.header['Status']
|
264
|
+
status = msg.header['Status']
|
265
|
+
if status == '404'
|
266
|
+
raise ::NATS::JetStream::Error::NotFound.new
|
267
|
+
else
|
268
|
+
raise JS.from_msg(msg)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
subject = msg.header['Nats-Subject']
|
272
|
+
seq = msg.header['Nats-Sequence']
|
273
|
+
raw_msg = JetStream::API::RawStreamMsg.new(
|
274
|
+
subject: subject,
|
275
|
+
seq: seq,
|
276
|
+
headers: msg.header,
|
277
|
+
)
|
278
|
+
raw_msg.data = msg.data
|
279
|
+
|
280
|
+
raw_msg
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Copyright 2021 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module NATS
|
16
|
+
class JetStream
|
17
|
+
module Msg
|
18
|
+
module Ack
|
19
|
+
# Ack types
|
20
|
+
Ack = ("+ACK".freeze)
|
21
|
+
Nak = ("-NAK".freeze)
|
22
|
+
Progress = ("+WPI".freeze)
|
23
|
+
Term = ("+TERM".freeze)
|
24
|
+
|
25
|
+
Empty = (''.freeze)
|
26
|
+
DotSep = ('.'.freeze)
|
27
|
+
NoDomainName = ('_'.freeze)
|
28
|
+
|
29
|
+
# Position
|
30
|
+
Prefix0 = ('$JS'.freeze)
|
31
|
+
Prefix1 = ('ACK'.freeze)
|
32
|
+
Domain = 2
|
33
|
+
AccHash = 3
|
34
|
+
Stream = 4
|
35
|
+
Consumer = 5
|
36
|
+
NumDelivered = 6
|
37
|
+
StreamSeq = 7
|
38
|
+
ConsumerSeq = 8
|
39
|
+
Timestamp = 9
|
40
|
+
NumPending = 10
|
41
|
+
|
42
|
+
# Subject without domain:
|
43
|
+
# $JS.ACK.<stream>.<consumer>.<delivered>.<sseq>.<cseq>.<tm>.<pending>
|
44
|
+
#
|
45
|
+
V1TokenCounts = 9
|
46
|
+
|
47
|
+
# Subject with domain:
|
48
|
+
# $JS.ACK.<domain>.<account hash>.<stream>.<consumer>.<delivered>.<sseq>.<cseq>.<tm>.<pending>.<a token with a random value>
|
49
|
+
#
|
50
|
+
V2TokenCounts = 12
|
51
|
+
|
52
|
+
SequencePair = Struct.new(:stream, :consumer)
|
53
|
+
end
|
54
|
+
private_constant :Ack
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# Copyright 2021 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
module NATS
|
16
|
+
class JetStream
|
17
|
+
module Msg
|
18
|
+
module AckMethods
|
19
|
+
def ack(**params)
|
20
|
+
ensure_is_acked_once!
|
21
|
+
|
22
|
+
resp = if params[:timeout]
|
23
|
+
@nc.request(@reply, Ack::Ack, **params)
|
24
|
+
else
|
25
|
+
@nc.publish(@reply, Ack::Ack)
|
26
|
+
end
|
27
|
+
@sub.synchronize { @ackd = true }
|
28
|
+
|
29
|
+
resp
|
30
|
+
end
|
31
|
+
|
32
|
+
def ack_sync(**params)
|
33
|
+
ensure_is_acked_once!
|
34
|
+
|
35
|
+
params[:timeout] ||= 0.5
|
36
|
+
resp = @nc.request(@reply, Ack::Ack, **params)
|
37
|
+
@sub.synchronize { @ackd = true }
|
38
|
+
|
39
|
+
resp
|
40
|
+
end
|
41
|
+
|
42
|
+
def nak(**params)
|
43
|
+
ensure_is_acked_once!
|
44
|
+
|
45
|
+
resp = if params[:timeout]
|
46
|
+
@nc.request(@reply, Ack::Nak, **params)
|
47
|
+
else
|
48
|
+
@nc.publish(@reply, Ack::Nak)
|
49
|
+
end
|
50
|
+
@sub.synchronize { @ackd = true }
|
51
|
+
|
52
|
+
resp
|
53
|
+
end
|
54
|
+
|
55
|
+
def term(**params)
|
56
|
+
ensure_is_acked_once!
|
57
|
+
|
58
|
+
resp = if params[:timeout]
|
59
|
+
@nc.request(@reply, Ack::Term, **params)
|
60
|
+
else
|
61
|
+
@nc.publish(@reply, Ack::Term)
|
62
|
+
end
|
63
|
+
@sub.synchronize { @ackd = true }
|
64
|
+
|
65
|
+
resp
|
66
|
+
end
|
67
|
+
|
68
|
+
def in_progress(**params)
|
69
|
+
params[:timeout] ? @nc.request(@reply, Ack::Progress, **params) : @nc.publish(@reply, Ack::Progress)
|
70
|
+
end
|
71
|
+
|
72
|
+
def metadata
|
73
|
+
@meta ||= parse_metadata(reply)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def ensure_is_acked_once!
|
79
|
+
@sub.synchronize do
|
80
|
+
if @ackd
|
81
|
+
raise JetStream::Error::MsgAlreadyAckd.new("nats: message was already acknowledged: #{self}")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_metadata(reply)
|
87
|
+
tokens = reply.split(Ack::DotSep)
|
88
|
+
n = tokens.count
|
89
|
+
|
90
|
+
case
|
91
|
+
when n < Ack::V1TokenCounts || (n > Ack::V1TokenCounts and n < Ack::V2TokenCounts)
|
92
|
+
raise NotJSMessage.new("nats: not a jetstream message")
|
93
|
+
when tokens[0] != Ack::Prefix0 || tokens[1] != Ack::Prefix1
|
94
|
+
raise NotJSMessage.new("nats: not a jetstream message")
|
95
|
+
when n == Ack::V1TokenCounts
|
96
|
+
tokens.insert(Ack::Domain, Ack::Empty)
|
97
|
+
tokens.insert(Ack::AccHash, Ack::Empty)
|
98
|
+
when tokens[Ack::Domain] == Ack::NoDomainName
|
99
|
+
tokens[Ack::Domain] = Ack::Empty
|
100
|
+
end
|
101
|
+
|
102
|
+
Metadata.new(tokens)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Copyright 2021 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
require 'time'
|
16
|
+
|
17
|
+
module NATS
|
18
|
+
class JetStream
|
19
|
+
module Msg
|
20
|
+
class Metadata
|
21
|
+
attr_reader :sequence, :num_delivered, :num_pending, :timestamp, :stream, :consumer, :domain
|
22
|
+
|
23
|
+
def initialize(opts)
|
24
|
+
@sequence = Ack::SequencePair.new(opts[Ack::StreamSeq].to_i, opts[Ack::ConsumerSeq].to_i)
|
25
|
+
@domain = opts[Ack::Domain]
|
26
|
+
@num_delivered = opts[Ack::NumDelivered].to_i
|
27
|
+
@num_pending = opts[Ack::NumPending].to_i
|
28
|
+
@timestamp = Time.at((opts[Ack::Timestamp].to_i / 1_000_000_000.0))
|
29
|
+
@stream = opts[Ack::Stream]
|
30
|
+
@consumer = opts[Ack::Consumer]
|
31
|
+
# TODO: Not exposed in Go client either right now.
|
32
|
+
# account = opts[Ack::AccHash]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright 2021 The NATS Authors
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
|
+
# you may not use this file except in compliance with the License.
|
4
|
+
# You may obtain a copy of the License at
|
5
|
+
#
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
#
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
11
|
+
# See the License for the specific language governing permissions and
|
12
|
+
# limitations under the License.
|
13
|
+
#
|
14
|
+
|
15
|
+
require_relative 'msg/ack'
|
16
|
+
require_relative 'msg/ack_methods'
|
17
|
+
require_relative 'msg/metadata'
|
18
|
+
|
19
|
+
module NATS
|
20
|
+
class JetStream
|
21
|
+
# JetStream::Msg module includes the methods so that a regular NATS::Msg
|
22
|
+
# can be enhanced with JetStream features like acking and metadata.
|
23
|
+
module Msg
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|