nats-pure 2.0.0.pre.rc1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/nats/io/client.rb +14 -26
- data/lib/nats/io/js.rb +57 -14
- data/lib/nats/io/kv.rb +172 -0
- data/lib/nats/io/version.rb +2 -2
- data/lib/nats/nuid.rb +3 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f0d4251703ba9fd6a91f501686025e2f71e93dc7869f65984da7cd312361266
|
4
|
+
data.tar.gz: 411fdfd23878cf89b26c76e04b68c760e10aaef14f2a68fae19c69a8d1392990
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3b88a713e2c1b6a515ac4f505cb6724c0059e72693d8d5c2ee61f3579d1b4b846408282e131864735dccc8b224e4a22933be91409d404fedadf0ec6c72051cf
|
7
|
+
data.tar.gz: 9ef88d1a391c2cfec91731aca2742382634c923384b801fce4ee9155418de39bd538f7aaafceb6ba2a1b40b57c6b7db4363ad4cf673d8ff3b5e87b5f74104789
|
data/lib/nats/io/client.rb
CHANGED
@@ -227,6 +227,7 @@ module NATS
|
|
227
227
|
opts[:pedantic] = false if opts[:pedantic].nil?
|
228
228
|
opts[:reconnect] = true if opts[:reconnect].nil?
|
229
229
|
opts[:old_style_request] = false if opts[:old_style_request].nil?
|
230
|
+
opts[:ignore_discovered_urls] = false if opts[:ignore_discovered_urls].nil?
|
230
231
|
opts[:reconnect_time_wait] = NATS::IO::RECONNECT_TIME_WAIT if opts[:reconnect_time_wait].nil?
|
231
232
|
opts[:max_reconnect_attempts] = NATS::IO::MAX_RECONNECT_ATTEMPTS if opts[:max_reconnect_attempts].nil?
|
232
233
|
opts[:ping_interval] = NATS::IO::DEFAULT_PING_INTERVAL if opts[:ping_interval].nil?
|
@@ -237,6 +238,7 @@ module NATS
|
|
237
238
|
opts[:pedantic] = ENV['NATS_PEDANTIC'].downcase == 'true' unless ENV['NATS_PEDANTIC'].nil?
|
238
239
|
opts[:reconnect] = ENV['NATS_RECONNECT'].downcase == 'true' unless ENV['NATS_RECONNECT'].nil?
|
239
240
|
opts[:reconnect_time_wait] = ENV['NATS_RECONNECT_TIME_WAIT'].to_i unless ENV['NATS_RECONNECT_TIME_WAIT'].nil?
|
241
|
+
opts[:ignore_discovered_urls] = ENV['NATS_IGNORE_DISCOVERED_URLS'].downcase == 'true' unless ENV['NATS_IGNORE_DISCOVERED_URLS'].nil?
|
240
242
|
opts[:max_reconnect_attempts] = ENV['NATS_MAX_RECONNECT_ATTEMPTS'].to_i unless ENV['NATS_MAX_RECONNECT_ATTEMPTS'].nil?
|
241
243
|
opts[:ping_interval] = ENV['NATS_PING_INTERVAL'].to_i unless ENV['NATS_PING_INTERVAL'].nil?
|
242
244
|
opts[:max_outstanding_pings] = ENV['NATS_MAX_OUTSTANDING_PINGS'].to_i unless ENV['NATS_MAX_OUTSTANDING_PINGS'].nil?
|
@@ -256,7 +258,7 @@ module NATS
|
|
256
258
|
end
|
257
259
|
@server_pool << {
|
258
260
|
:uri => nats_uri,
|
259
|
-
:hostname => nats_uri.
|
261
|
+
:hostname => nats_uri.hostname
|
260
262
|
}
|
261
263
|
end
|
262
264
|
|
@@ -807,17 +809,17 @@ module NATS
|
|
807
809
|
|
808
810
|
# Detect any announced server that we might not be aware of...
|
809
811
|
connect_urls = @server_info[:connect_urls]
|
810
|
-
if connect_urls
|
812
|
+
if !@options[:ignore_discovered_urls] && connect_urls
|
811
813
|
srvs = []
|
812
814
|
connect_urls.each do |url|
|
813
815
|
scheme = client_using_secure_connection? ? "tls" : "nats"
|
814
816
|
u = URI.parse("#{scheme}://#{url}")
|
815
817
|
|
816
818
|
# Skip in case it is the current server which we already know
|
817
|
-
next if @uri.
|
819
|
+
next if @uri.hostname == u.hostname && @uri.port == u.port
|
818
820
|
|
819
821
|
present = server_pool.detect do |srv|
|
820
|
-
srv[:uri].
|
822
|
+
srv[:uri].hostname == u.hostname && srv[:uri].port == u.port
|
821
823
|
end
|
822
824
|
|
823
825
|
if not present
|
@@ -832,7 +834,7 @@ module NATS
|
|
832
834
|
end
|
833
835
|
|
834
836
|
# NOTE: Auto discovery won't work here when TLS host verification is enabled.
|
835
|
-
srv = { :uri => u, :reconnect_attempts => 0, :discovered => true, :hostname => u.
|
837
|
+
srv = { :uri => u, :reconnect_attempts => 0, :discovered => true, :hostname => u.hostname }
|
836
838
|
srvs << srv
|
837
839
|
end
|
838
840
|
end
|
@@ -1758,34 +1760,20 @@ module NATS
|
|
1758
1760
|
end
|
1759
1761
|
|
1760
1762
|
def process_uri(uris)
|
1761
|
-
|
1762
|
-
uris.split(',').each do |uri|
|
1763
|
+
uris.split(',').map do |uri|
|
1763
1764
|
opts = {}
|
1764
1765
|
|
1765
1766
|
# Scheme
|
1766
|
-
if uri.include?("://")
|
1767
|
-
scheme, uri = uri.split("://")
|
1768
|
-
opts[:scheme] = scheme
|
1769
|
-
else
|
1770
|
-
opts[:scheme] = 'nats'
|
1771
|
-
end
|
1767
|
+
uri = "nats://#{uri}" if !uri.include?("://")
|
1772
1768
|
|
1773
|
-
|
1774
|
-
if uri.include?("@")
|
1775
|
-
userinfo, endpoint = uri.split("@")
|
1776
|
-
host, port = endpoint.split(":")
|
1777
|
-
opts[:userinfo] = userinfo
|
1778
|
-
else
|
1779
|
-
host, port = uri.split(":")
|
1780
|
-
end
|
1769
|
+
uri_object = URI(uri)
|
1781
1770
|
|
1782
1771
|
# Host and Port
|
1783
|
-
|
1784
|
-
|
1772
|
+
uri_object.hostname ||= "localhost"
|
1773
|
+
uri_object.port ||= DEFAULT_PORT
|
1785
1774
|
|
1786
|
-
|
1775
|
+
uri_object
|
1787
1776
|
end
|
1788
|
-
connect_uris
|
1789
1777
|
end
|
1790
1778
|
end
|
1791
1779
|
|
@@ -1834,7 +1822,7 @@ module NATS
|
|
1834
1822
|
end
|
1835
1823
|
|
1836
1824
|
def connect
|
1837
|
-
addrinfo = ::Socket.getaddrinfo(@uri.
|
1825
|
+
addrinfo = ::Socket.getaddrinfo(@uri.hostname, nil, ::Socket::AF_UNSPEC, ::Socket::SOCK_STREAM)
|
1838
1826
|
addrinfo.each_with_index do |ai, i|
|
1839
1827
|
begin
|
1840
1828
|
@socket = connect_addrinfo(ai, @uri.port, @connect_timeout)
|
data/lib/nats/io/js.rb
CHANGED
@@ -284,6 +284,7 @@ module NATS
|
|
284
284
|
end
|
285
285
|
stream = config[:name]
|
286
286
|
raise ArgumentError.new(":name is required to create streams") unless stream
|
287
|
+
raise ArgumentError.new("Spaces, tabs, period (.), greater than (>) or asterisk (*) are prohibited in stream names") if stream =~ /(\s|\.|\>|\*)/
|
287
288
|
req_subject = "#{@prefix}.STREAM.CREATE.#{stream}"
|
288
289
|
result = api_request(req_subject, config.to_json, params)
|
289
290
|
JetStream::API::StreamCreateResponse.new(result)
|
@@ -345,6 +346,7 @@ module NATS
|
|
345
346
|
stream_name: stream,
|
346
347
|
config: config
|
347
348
|
}
|
349
|
+
|
348
350
|
result = api_request(req_subject, req.to_json, params)
|
349
351
|
JetStream::API::ConsumerInfo.new(result).freeze
|
350
352
|
end
|
@@ -502,11 +504,14 @@ module NATS
|
|
502
504
|
synchronize do
|
503
505
|
unless @pending_queue.empty?
|
504
506
|
msg = @pending_queue.pop
|
507
|
+
@pending_size -= msg.data.size
|
505
508
|
# Check for a no msgs response status.
|
506
509
|
if JS.is_status_msg(msg)
|
507
510
|
case msg.header["Status"]
|
508
511
|
when JS::Status::NoMsgs
|
509
512
|
msg = nil
|
513
|
+
when JS::Status::RequestTimeout
|
514
|
+
# Skip
|
510
515
|
else
|
511
516
|
raise JS.from_msg(msg)
|
512
517
|
end
|
@@ -525,7 +530,12 @@ module NATS
|
|
525
530
|
# Wait for result of fetch or timeout.
|
526
531
|
synchronize { wait_for_msgs_cond.wait(timeout) }
|
527
532
|
|
528
|
-
|
533
|
+
unless @pending_queue.empty?
|
534
|
+
msg = @pending_queue.pop
|
535
|
+
@pending_size -= msg.data.size
|
536
|
+
|
537
|
+
msgs << msg
|
538
|
+
end
|
529
539
|
|
530
540
|
duration = MonotonicTime.since(t)
|
531
541
|
if duration > timeout
|
@@ -535,7 +545,13 @@ module NATS
|
|
535
545
|
# Should have received at least a message at this point,
|
536
546
|
# if that is not the case then error already.
|
537
547
|
if JS.is_status_msg(msgs.first)
|
538
|
-
|
548
|
+
msg = msgs.first
|
549
|
+
case msg.header[JS::Header::Status]
|
550
|
+
when JS::Status::RequestTimeout
|
551
|
+
raise NATS::Timeout.new("nats: fetch request timeout")
|
552
|
+
else
|
553
|
+
raise JS.from_msg(msgs.first)
|
554
|
+
end
|
539
555
|
end
|
540
556
|
end
|
541
557
|
when batch > 1
|
@@ -546,7 +562,23 @@ module NATS
|
|
546
562
|
# Check if there already enough in the pending buffer.
|
547
563
|
synchronize do
|
548
564
|
if batch <= @pending_queue.size
|
549
|
-
batch.times
|
565
|
+
batch.times do
|
566
|
+
msg = @pending_queue.pop
|
567
|
+
@pending_size -= msg.data.size
|
568
|
+
|
569
|
+
# Check for a no msgs response status.
|
570
|
+
if JS.is_status_msg(msg)
|
571
|
+
case msg.header[JS::Header::Status]
|
572
|
+
when JS::Status::NoMsgs, JS::Status::RequestTimeout
|
573
|
+
# Skip these
|
574
|
+
next
|
575
|
+
else
|
576
|
+
raise JS.from_msg(msg)
|
577
|
+
end
|
578
|
+
else
|
579
|
+
msgs << msg
|
580
|
+
end
|
581
|
+
end
|
550
582
|
|
551
583
|
return msgs
|
552
584
|
end
|
@@ -559,10 +591,15 @@ module NATS
|
|
559
591
|
# Not receiving even one is a timeout.
|
560
592
|
start_time = MonotonicTime.now
|
561
593
|
msg = nil
|
562
|
-
|
594
|
+
|
595
|
+
synchronize do
|
563
596
|
wait_for_msgs_cond.wait(timeout)
|
564
|
-
|
565
|
-
|
597
|
+
|
598
|
+
unless @pending_queue.empty?
|
599
|
+
msg = @pending_queue.pop
|
600
|
+
@pending_size -= msg.data.size
|
601
|
+
end
|
602
|
+
end
|
566
603
|
|
567
604
|
# Check if the first message was a response saying that
|
568
605
|
# there are no messages.
|
@@ -574,11 +611,13 @@ module NATS
|
|
574
611
|
next_req.delete(:no_wait)
|
575
612
|
|
576
613
|
@nc.publish(@jsi.nms, JS.next_req_to_json(next_req), @subject)
|
614
|
+
when JS::Status::RequestTimeout
|
615
|
+
raise NATS::Timeout.new("nats: fetch request timeout")
|
577
616
|
else
|
578
617
|
raise JS.from_msg(msg)
|
579
618
|
end
|
580
619
|
else
|
581
|
-
msgs << msg
|
620
|
+
msgs << msg unless msg.nil?
|
582
621
|
end
|
583
622
|
|
584
623
|
# Check if have not received yet a single message.
|
@@ -605,23 +644,27 @@ module NATS
|
|
605
644
|
end
|
606
645
|
else
|
607
646
|
msg = @pending_queue.pop
|
647
|
+
@pending_size -= msg.data.size
|
608
648
|
|
609
649
|
if JS.is_status_msg(msg)
|
610
|
-
case msg.header[
|
650
|
+
case msg.header[JS::Header::Status]
|
611
651
|
when JS::Status::NoMsgs, JS::Status::RequestTimeout
|
612
652
|
duration = MonotonicTime.since(start_time)
|
613
653
|
|
614
|
-
|
615
|
-
|
616
|
-
|
654
|
+
if duration > timeout
|
655
|
+
# Only received a subset of the messages.
|
656
|
+
if !msgs.empty?
|
657
|
+
return msgs
|
658
|
+
else
|
659
|
+
raise NATS::Timeout.new("nats: fetch timeout")
|
660
|
+
end
|
617
661
|
end
|
618
|
-
|
619
|
-
# Likely only received a subset of the messages.
|
620
|
-
return msgs
|
621
662
|
else
|
622
663
|
raise JS.from_msg(msg)
|
623
664
|
end
|
665
|
+
|
624
666
|
else
|
667
|
+
# Add to the set of messages that will be returned.
|
625
668
|
msgs << msg
|
626
669
|
needed -= 1
|
627
670
|
end
|
data/lib/nats/io/kv.rb
ADDED
@@ -0,0 +1,172 @@
|
|
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
|
+
require_relative 'errors'
|
15
|
+
|
16
|
+
module NATS
|
17
|
+
class KeyValue
|
18
|
+
KV_OP = "KV-Operation"
|
19
|
+
KV_DEL = "DEL"
|
20
|
+
KV_PURGE = "PURGE"
|
21
|
+
MSG_ROLLUP_SUBJECT = "sub"
|
22
|
+
MSG_ROLLUP_ALL = "all"
|
23
|
+
|
24
|
+
def initialize(opts={})
|
25
|
+
@name = opts[:name]
|
26
|
+
@stream = opts[:stream]
|
27
|
+
@pre = opts[:pre]
|
28
|
+
@js = opts[:js]
|
29
|
+
end
|
30
|
+
|
31
|
+
# When a key is not found because it was deleted.
|
32
|
+
class KeyDeletedError < NATS::Error; end
|
33
|
+
|
34
|
+
# When there was no bucket present.
|
35
|
+
class BucketNotFoundError < NATS::Error; end
|
36
|
+
|
37
|
+
# When it is an invalid bucket.
|
38
|
+
class BadBucketError < NATS::Error; end
|
39
|
+
|
40
|
+
# get returns the latest value for the key.
|
41
|
+
def get(key)
|
42
|
+
msg = @js.get_last_msg(@stream, "#{@pre}#{key}")
|
43
|
+
entry = Entry.new(bucket: @name, key: key, value: msg.data, revision: msg.seq)
|
44
|
+
|
45
|
+
if not msg.headers.nil?
|
46
|
+
op = msg.headers[KV_OP]
|
47
|
+
raise KeyDeletedError.new("nats: key was deleted") if op == KV_DEL or op == KV_PURGE
|
48
|
+
end
|
49
|
+
|
50
|
+
entry
|
51
|
+
end
|
52
|
+
|
53
|
+
# put will place the new value for the key into the store
|
54
|
+
# and return the revision number.
|
55
|
+
def put(key, value)
|
56
|
+
@js.publish("#{@pre}#{key}", value)
|
57
|
+
end
|
58
|
+
|
59
|
+
# delete will place a delete marker and remove all previous revisions.
|
60
|
+
def delete(key)
|
61
|
+
hdrs = {}
|
62
|
+
hdrs[KV_OP] = KV_DEL
|
63
|
+
@js.publish("#{@pre}#{key}", header: hdrs)
|
64
|
+
end
|
65
|
+
|
66
|
+
# status retrieves the status and configuration of a bucket.
|
67
|
+
def status
|
68
|
+
info = @js.stream_info(@stream)
|
69
|
+
BucketStatus.new(info, @name)
|
70
|
+
end
|
71
|
+
|
72
|
+
Entry = Struct.new(:bucket, :key, :value, :revision, keyword_init: true) do
|
73
|
+
def initialize(opts={})
|
74
|
+
rem = opts.keys - members
|
75
|
+
opts.delete_if { |k| rem.include?(k) }
|
76
|
+
super(opts)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class BucketStatus
|
81
|
+
attr_reader :bucket
|
82
|
+
|
83
|
+
def initialize(info, bucket)
|
84
|
+
@nfo = info
|
85
|
+
@bucket = bucket
|
86
|
+
end
|
87
|
+
|
88
|
+
def values
|
89
|
+
@nfo.state.messages
|
90
|
+
end
|
91
|
+
|
92
|
+
def history
|
93
|
+
@nfo.config.max_msgs_per_subject
|
94
|
+
end
|
95
|
+
|
96
|
+
def ttl
|
97
|
+
@nfo.config.max_age / 1_000_000_000
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
module API
|
102
|
+
KeyValueConfig = Struct.new(:bucket, :description, :max_value_size,
|
103
|
+
:history, :ttl, :max_bytes, :storage, :replicas,
|
104
|
+
keyword_init: true) do
|
105
|
+
def initialize(opts={})
|
106
|
+
rem = opts.keys - members
|
107
|
+
opts.delete_if { |k| rem.include?(k) }
|
108
|
+
super(opts)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
module Manager
|
114
|
+
def key_value(bucket)
|
115
|
+
stream = "KV_#{bucket}"
|
116
|
+
begin
|
117
|
+
si = stream_info(stream)
|
118
|
+
rescue NATS::JetStream::Error::NotFound
|
119
|
+
raise BucketNotFoundError.new("nats: bucket not found")
|
120
|
+
end
|
121
|
+
if si.config.max_msgs_per_subject < 1
|
122
|
+
raise BadBucketError.new("nats: bad bucket")
|
123
|
+
end
|
124
|
+
|
125
|
+
KeyValue.new(
|
126
|
+
name: bucket,
|
127
|
+
stream: stream,
|
128
|
+
pre: "$KV.#{bucket}.",
|
129
|
+
js: self,
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def create_key_value(config)
|
134
|
+
config = if not config.is_a?(JetStream::API::StreamConfig)
|
135
|
+
KeyValue::API::KeyValueConfig.new(config)
|
136
|
+
else
|
137
|
+
config
|
138
|
+
end
|
139
|
+
config.history ||= 1
|
140
|
+
config.replicas ||= 1
|
141
|
+
if config.ttl
|
142
|
+
config.ttl = config.ttl * 1_000_000_000
|
143
|
+
end
|
144
|
+
|
145
|
+
stream = JetStream::API::StreamConfig.new(
|
146
|
+
name: "KV_#{config.bucket}",
|
147
|
+
subjects: ["$KV.#{config.bucket}.>"],
|
148
|
+
max_msgs_per_subject: config.history,
|
149
|
+
max_bytes: config.max_bytes,
|
150
|
+
max_age: config.ttl,
|
151
|
+
max_msg_size: config.max_value_size,
|
152
|
+
storage: config.storage,
|
153
|
+
num_replicas: config.replicas,
|
154
|
+
allow_rollup_hdrs: true,
|
155
|
+
deny_delete: true,
|
156
|
+
)
|
157
|
+
resp = add_stream(stream)
|
158
|
+
|
159
|
+
KeyValue.new(
|
160
|
+
name: config.bucket,
|
161
|
+
stream: stream.name,
|
162
|
+
pre: "$KV.#{config.bucket}.",
|
163
|
+
js: self,
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
def delete_key_value(bucket)
|
168
|
+
delete_stream("KV_#{bucket}")
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
data/lib/nats/io/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2016-
|
1
|
+
# Copyright 2016-2022 The NATS Authors
|
2
2
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
3
3
|
# you may not use this file except in compliance with the License.
|
4
4
|
# You may obtain a copy of the License at
|
@@ -15,7 +15,7 @@
|
|
15
15
|
module NATS
|
16
16
|
module IO
|
17
17
|
# VERSION is the version of the client announced on CONNECT to the server.
|
18
|
-
VERSION = "2.
|
18
|
+
VERSION = "2.1.0".freeze
|
19
19
|
|
20
20
|
# LANG is the lang runtime of the client announced on CONNECT to the server.
|
21
21
|
LANG = "#{RUBY_ENGINE}#{RUBY_VERSION}".freeze
|
data/lib/nats/nuid.rb
CHANGED
@@ -15,7 +15,7 @@ require 'securerandom'
|
|
15
15
|
|
16
16
|
module NATS
|
17
17
|
class NUID
|
18
|
-
DIGITS
|
18
|
+
DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
|
19
19
|
BASE = 62
|
20
20
|
PREFIX_LENGTH = 12
|
21
21
|
SEQ_LENGTH = 10
|
@@ -25,6 +25,8 @@ module NATS
|
|
25
25
|
MAX_INC = 333
|
26
26
|
INC = MAX_INC - MIN_INC
|
27
27
|
|
28
|
+
Ractor.make_shareable(DIGITS) if defined?(Ractor)
|
29
|
+
|
28
30
|
def initialize
|
29
31
|
@prand = Random.new
|
30
32
|
@seq = @prand.rand(MAX_SEQ)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nats-pure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Waldemar Quevedo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: NATS is an open-source, high-performance, lightweight cloud messaging
|
14
14
|
system.
|
@@ -23,6 +23,7 @@ files:
|
|
23
23
|
- lib/nats/io/client.rb
|
24
24
|
- lib/nats/io/errors.rb
|
25
25
|
- lib/nats/io/js.rb
|
26
|
+
- lib/nats/io/kv.rb
|
26
27
|
- lib/nats/io/msg.rb
|
27
28
|
- lib/nats/io/parser.rb
|
28
29
|
- lib/nats/io/subscription.rb
|
@@ -43,11 +44,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
43
44
|
version: '0'
|
44
45
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
46
|
requirements:
|
46
|
-
- - "
|
47
|
+
- - ">="
|
47
48
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
49
|
+
version: '0'
|
49
50
|
requirements: []
|
50
|
-
rubygems_version: 3.
|
51
|
+
rubygems_version: 3.3.3
|
51
52
|
signing_key:
|
52
53
|
specification_version: 4
|
53
54
|
summary: NATS is an open-source, high-performance, lightweight cloud messaging system.
|