nats-pure 2.2.1 → 2.4.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -0
  3. data/README.md +251 -0
  4. data/lib/nats/client.rb +1 -0
  5. data/lib/nats/io/client.rb +214 -144
  6. data/lib/nats/io/errors.rb +6 -0
  7. data/lib/nats/io/jetstream/api.rb +4 -0
  8. data/lib/nats/io/jetstream/manager.rb +21 -2
  9. data/lib/nats/io/jetstream/msg/ack_methods.rb +8 -4
  10. data/lib/nats/io/jetstream.rb +82 -7
  11. data/lib/nats/io/msg.rb +3 -1
  12. data/lib/nats/io/rails.rb +29 -0
  13. data/lib/nats/io/subscription.rb +70 -5
  14. data/lib/nats/io/version.rb +1 -1
  15. data/lib/nats/io/websocket.rb +75 -0
  16. data/sig/nats/io/client.rbs +304 -0
  17. data/sig/nats/io/errors.rbs +54 -0
  18. data/sig/nats/io/jetstream/api.rbs +35 -0
  19. data/sig/nats/io/jetstream/errors.rbs +54 -0
  20. data/sig/nats/io/jetstream/js/config.rbs +11 -0
  21. data/sig/nats/io/jetstream/js/header.rbs +17 -0
  22. data/sig/nats/io/jetstream/js/status.rbs +13 -0
  23. data/sig/nats/io/jetstream/js/sub.rbs +14 -0
  24. data/sig/nats/io/jetstream/js.rbs +27 -0
  25. data/sig/nats/io/jetstream/manager.rbs +33 -0
  26. data/sig/nats/io/jetstream/msg/ack.rbs +35 -0
  27. data/sig/nats/io/jetstream/msg/ack_methods.rbs +25 -0
  28. data/sig/nats/io/jetstream/msg/metadata.rbs +15 -0
  29. data/sig/nats/io/jetstream/msg.rbs +6 -0
  30. data/sig/nats/io/jetstream/pull_subscription.rbs +14 -0
  31. data/sig/nats/io/jetstream/push_subscription.rbs +7 -0
  32. data/sig/nats/io/jetstream.rbs +15 -0
  33. data/sig/nats/io/kv/api.rbs +8 -0
  34. data/sig/nats/io/kv/bucket_status.rbs +17 -0
  35. data/sig/nats/io/kv/errors.rbs +30 -0
  36. data/sig/nats/io/kv/manager.rbs +11 -0
  37. data/sig/nats/io/kv.rbs +39 -0
  38. data/sig/nats/io/msg.rbs +14 -0
  39. data/sig/nats/io/parser.rbs +32 -0
  40. data/sig/nats/io/subscription.rbs +33 -0
  41. data/sig/nats/io/version.rbs +9 -0
  42. data/sig/nats/nuid.rbs +32 -0
  43. metadata +49 -4
@@ -41,11 +41,15 @@ module NATS
41
41
 
42
42
  def nak(**params)
43
43
  ensure_is_acked_once!
44
-
44
+ payload = if params[:delay]
45
+ payload = "#{Ack::Nak} #{{ delay: params[:delay] }.to_json}"
46
+ else
47
+ Ack::Nak
48
+ end
45
49
  resp = if params[:timeout]
46
- @nc.request(@reply, Ack::Nak, **params)
50
+ @nc.request(@reply, payload, **params)
47
51
  else
48
- @nc.publish(@reply, Ack::Nak)
52
+ @nc.publish(@reply, payload)
49
53
  end
50
54
  @sub.synchronize { @ackd = true }
51
55
 
@@ -104,4 +108,4 @@ module NATS
104
108
  end
105
109
  end
106
110
  end
107
- end
111
+ end
@@ -105,16 +105,50 @@ module NATS
105
105
 
106
106
  # subscribe binds or creates a push subscription to a JetStream pull consumer.
107
107
  #
108
- # @param subject [String] Subject from which the messages will be fetched.
108
+ # @param subject [String, Array] Subject(s) from which the messages will be fetched.
109
109
  # @param params [Hash] Options to customize the PushSubscription.
110
110
  # @option params [String] :stream Name of the Stream to which the consumer belongs.
111
111
  # @option params [String] :consumer Name of the Consumer to which the PushSubscription will be bound.
112
+ # @option params [String] :name Name of the Consumer to which the PushSubscription will be bound.
112
113
  # @option params [String] :durable Consumer durable name from where the messages will be fetched.
113
114
  # @option params [Hash] :config Configuration for the consumer.
114
115
  # @return [NATS::JetStream::PushSubscription]
115
116
  def subscribe(subject, params={}, &cb)
116
117
  params[:consumer] ||= params[:durable]
117
- stream = params[:stream].nil? ? find_stream_name_by_subject(subject) : params[:stream]
118
+ params[:consumer] ||= params[:name]
119
+ multi_filter = case
120
+ when (subject.is_a?(Array) and subject.size == 1)
121
+ subject = subject.first
122
+ false
123
+ when (subject.is_a?(Array) and subject.size > 1)
124
+ true
125
+ end
126
+
127
+ #
128
+ stream = if params[:stream].nil?
129
+ if multi_filter
130
+ # Use the first subject to try to find the stream.
131
+ streams = subject.map do |s|
132
+ begin
133
+ find_stream_name_by_subject(s)
134
+ rescue NATS::JetStream::Error::NotFound
135
+ raise NATS::JetStream::Error.new("nats: could not find stream matching filter subject '#{s}'")
136
+ end
137
+ end
138
+
139
+ # Ensure that the filter subjects are not ambiguous.
140
+ streams.uniq!
141
+ if streams.count > 1
142
+ raise NATS::JetStream::Error.new("nats: multiple streams matched filter subjects: #{streams}")
143
+ end
144
+
145
+ streams.first
146
+ else
147
+ find_stream_name_by_subject(subject)
148
+ end
149
+ else
150
+ params[:stream]
151
+ end
118
152
 
119
153
  queue = params[:queue]
120
154
  durable = params[:durable]
@@ -183,7 +217,11 @@ module NATS
183
217
  config.deliver_subject = deliver
184
218
 
185
219
  # Auto created consumers use the filter subject.
186
- config.filter_subject = subject
220
+ if multi_filter
221
+ config[:filter_subjects] ||= subject
222
+ else
223
+ config[:filter_subject] ||= subject
224
+ end
187
225
 
188
226
  # Heartbeats / FlowControl
189
227
  config.flow_control = flow_control
@@ -219,25 +257,57 @@ module NATS
219
257
 
220
258
  # pull_subscribe binds or creates a subscription to a JetStream pull consumer.
221
259
  #
222
- # @param subject [String] Subject from which the messages will be fetched.
260
+ # @param subject [String, Array] Subject or subjects from which the messages will be fetched.
223
261
  # @param durable [String] Consumer durable name from where the messages will be fetched.
224
262
  # @param params [Hash] Options to customize the PullSubscription.
225
263
  # @option params [String] :stream Name of the Stream to which the consumer belongs.
226
264
  # @option params [String] :consumer Name of the Consumer to which the PullSubscription will be bound.
265
+ # @option params [String] :name Name of the Consumer to which the PullSubscription will be bound.
227
266
  # @option params [Hash] :config Configuration for the consumer.
228
267
  # @return [NATS::JetStream::PullSubscription]
229
268
  def pull_subscribe(subject, durable, params={})
230
- if durable.empty? && !params[:consumer]
269
+ if (!durable or durable.empty?) && !(params[:consumer] or params[:name])
231
270
  raise JetStream::Error::InvalidDurableName.new("nats: invalid durable name")
232
271
  end
272
+ multi_filter = case
273
+ when (subject.is_a?(Array) and subject.size == 1)
274
+ subject = subject.first
275
+ false
276
+ when (subject.is_a?(Array) and subject.size > 1)
277
+ true
278
+ end
279
+
233
280
  params[:consumer] ||= durable
234
- stream = params[:stream].nil? ? find_stream_name_by_subject(subject) : params[:stream]
281
+ params[:consumer] ||= params[:name]
282
+ stream = if params[:stream].nil?
283
+ if multi_filter
284
+ # Use the first subject to try to find the stream.
285
+ streams = subject.map do |s|
286
+ begin
287
+ find_stream_name_by_subject(s)
288
+ rescue NATS::JetStream::Error::NotFound
289
+ raise NATS::JetStream::Error.new("nats: could not find stream matching filter subject '#{s}'")
290
+ end
291
+ end
292
+
293
+ # Ensure that the filter subjects are not ambiguous.
294
+ streams.uniq!
295
+ if streams.count > 1
296
+ raise NATS::JetStream::Error.new("nats: multiple streams matched filter subjects: #{streams}")
297
+ end
235
298
 
299
+ streams.first
300
+ else
301
+ find_stream_name_by_subject(subject)
302
+ end
303
+ else
304
+ params[:stream]
305
+ end
236
306
  begin
237
307
  consumer_info(stream, params[:consumer])
238
308
  rescue NATS::JetStream::Error::NotFound => e
239
309
  # If attempting to bind, then this is a hard error.
240
- raise e if params[:stream]
310
+ raise e if params[:stream] and !multi_filter
241
311
 
242
312
  config = if not params[:config]
243
313
  JetStream::API::ConsumerConfig.new
@@ -248,6 +318,11 @@ module NATS
248
318
  end
249
319
  config[:durable_name] = durable
250
320
  config[:ack_policy] ||= JS::Config::AckExplicit
321
+ if multi_filter
322
+ config[:filter_subjects] ||= subject
323
+ else
324
+ config[:filter_subject] ||= subject
325
+ end
251
326
  add_consumer(stream, config)
252
327
  end
253
328
 
data/lib/nats/io/msg.rb CHANGED
@@ -50,7 +50,9 @@ module NATS
50
50
 
51
51
  def inspect
52
52
  hdr = ", header=#{@header}" if @header
53
- "#<NATS::Msg(subject: \"#{@subject}\", reply: \"#{@reply}\", data: #{@data.slice(0, 10).inspect}#{hdr})>"
53
+ dot = '...' if @data.length > 10
54
+ dat = "#{data.slice(0, 10)}#{dot}"
55
+ "#<NATS::Msg(subject: \"#{@subject}\", reply: \"#{@reply}\", data: #{dat.inspect}#{hdr})>"
54
56
  end
55
57
  end
56
58
  end
@@ -0,0 +1,29 @@
1
+ require "rails"
2
+
3
+ module NATS
4
+ class Rails < ::Rails::Engine
5
+ # This class is used to free resources managed by Rails (e.g. database connections)
6
+ # that were implicitly acquired in subscription callbacks
7
+ # Implementation is based on https://github.com/sidekiq/sidekiq/blob/5e1a77a6d03193dd977fbfe8961ab78df91bb392/lib/sidekiq/rails.rb
8
+ class Reloader
9
+ def initialize(app = ::Rails.application)
10
+ @app = app
11
+ end
12
+
13
+ def call
14
+ params = (::Rails::VERSION::STRING >= "7.1") ? {source: "gem.nats"} : {}
15
+ @app.reloader.wrap(**params) do
16
+ yield
17
+ end
18
+ end
19
+
20
+ def inspect
21
+ "#<NATS::Rails::Reloader @app=#{@app.class.name}>"
22
+ end
23
+ end
24
+
25
+ config.after_initialize do
26
+ NATS::Client.default_reloader = NATS::Rails::Reloader.new
27
+ end
28
+ end
29
+ end
@@ -28,14 +28,14 @@ module NATS
28
28
  include MonitorMixin
29
29
 
30
30
  attr_accessor :subject, :queue, :future, :callback, :response, :received, :max, :pending, :sid
31
- attr_accessor :pending_queue, :pending_size, :wait_for_msgs_t, :wait_for_msgs_cond, :is_slow_consumer
31
+ attr_accessor :pending_queue, :pending_size, :wait_for_msgs_cond, :concurrency_semaphore
32
32
  attr_accessor :pending_msgs_limit, :pending_bytes_limit
33
33
  attr_accessor :nc
34
34
  attr_accessor :jsi
35
35
  attr_accessor :closed
36
36
 
37
- def initialize
38
- super # required to initialize monitor
37
+ def initialize(**opts)
38
+ super() # required to initialize monitor
39
39
  @subject = ''
40
40
  @queue = nil
41
41
  @future = nil
@@ -53,11 +53,27 @@ module NATS
53
53
  @pending_size = 0
54
54
  @pending_msgs_limit = nil
55
55
  @pending_bytes_limit = nil
56
- @wait_for_msgs_t = nil
57
- @is_slow_consumer = false
58
56
 
59
57
  # Sync subscriber
60
58
  @wait_for_msgs_cond = nil
59
+
60
+ # To limit number of concurrent messages being processed (1 to only allow sequential processing)
61
+ @processing_concurrency = opts.fetch(:processing_concurrency, NATS::IO::DEFAULT_SINGLE_SUB_CONCURRENCY)
62
+ end
63
+
64
+ # Concurrency of message processing for a single subscription.
65
+ # 1 means sequential processing
66
+ # 2+ allow processed concurrently and possibly out of order.
67
+ def processing_concurrency=(value)
68
+ raise ArgumentError, "nats: subscription processing concurrency must be positive integer" unless value.positive?
69
+ return if @processing_concurrency == value
70
+
71
+ @processing_concurrency = value
72
+ @concurrency_semaphore = Concurrent::Semaphore.new(value)
73
+ end
74
+
75
+ def concurrency_semaphore
76
+ @concurrency_semaphore ||= Concurrent::Semaphore.new(@processing_concurrency)
61
77
  end
62
78
 
63
79
  # Auto unsubscribes the server by sending UNSUB command and throws away
@@ -88,5 +104,54 @@ module NATS
88
104
  def inspect
89
105
  "#<NATS::Subscription(subject: \"#{@subject}\", queue: \"#{@queue}\", sid: #{@sid})>"
90
106
  end
107
+
108
+ def dispatch(msg)
109
+ pending_queue << msg
110
+ synchronize { self.pending_size += msg.data.size }
111
+
112
+ # For async subscribers, send message for processing to the thread pool.
113
+ enqueue_processing(@nc.subscription_executor) if callback
114
+
115
+ # For sync subscribers, signal that there is a new message.
116
+ wait_for_msgs_cond&.signal
117
+ end
118
+
119
+ def process(msg)
120
+ return unless callback
121
+
122
+ # Decrease pending size since consumed already
123
+ synchronize { self.pending_size -= msg.data.size }
124
+
125
+ nc.reloader.call do
126
+ # Note: Keep some of the alternative arity versions to slightly
127
+ # improve backwards compatibility. Eventually fine to deprecate
128
+ # since recommended version would be arity of 1 to get a NATS::Msg.
129
+ case callback.arity
130
+ when 0 then callback.call
131
+ when 1 then callback.call(msg)
132
+ when 2 then callback.call(msg.data, msg.reply)
133
+ when 3 then callback.call(msg.data, msg.reply, msg.subject)
134
+ else callback.call(msg.data, msg.reply, msg.subject, msg.header)
135
+ end
136
+ rescue => e
137
+ synchronize { nc.send(:err_cb_call, nc, e, self) }
138
+ end
139
+ end
140
+
141
+ # Send a message for its processing to a separate thread
142
+ def enqueue_processing(executor)
143
+ concurrency_semaphore.try_acquire || return # Previous message is being executed, let it finish and enqueue next one.
144
+ executor.post do
145
+ msg = pending_queue.pop(true)
146
+ process(msg)
147
+ rescue ThreadError # queue is empty
148
+ concurrency_semaphore.release
149
+ ensure
150
+ concurrency_semaphore.release
151
+ [concurrency_semaphore.available_permits, pending_queue.size].min.times do
152
+ enqueue_processing(executor)
153
+ end
154
+ end
155
+ end
91
156
  end
92
157
  end
@@ -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.2.1".freeze
18
+ VERSION = "2.4.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
@@ -0,0 +1,75 @@
1
+ begin
2
+ require 'websocket'
3
+ rescue LoadError
4
+ raise LoadError, "Please add `websocket` gem to your Gemfile to connect to NATS via WebSocket."
5
+ end
6
+
7
+ module NATS
8
+ module IO
9
+ # WebSocket to connect to NATS via WebSocket and automatically decode and encode frames.
10
+
11
+ # @see https://docs.nats.io/running-a-nats-service/configuration/websocket
12
+
13
+ class WebSocket < Socket
14
+ class HandshakeError < RuntimeError; end
15
+
16
+ attr_accessor :socket
17
+
18
+ def initialize(options={})
19
+ super
20
+ end
21
+
22
+ def connect
23
+ super
24
+
25
+ setup_tls! if @uri.scheme == "wss" # WebSocket connection must be made over TLS from the beginning
26
+
27
+ @handshake = ::WebSocket::Handshake::Client.new url: @uri.to_s
28
+ @frame = ::WebSocket::Frame::Incoming::Client.new
29
+ @handshaked = false
30
+
31
+ @socket.write @handshake.to_s
32
+
33
+ until @handshaked
34
+ @handshake << method(:read).super_method.call(MAX_SOCKET_READ_BYTES)
35
+ if @handshake.finished?
36
+ @handshaked = true
37
+ end
38
+ end
39
+ end
40
+
41
+ def setup_tls!
42
+ return if @socket.is_a? OpenSSL::SSL::SSLSocket
43
+
44
+ super
45
+ end
46
+
47
+ def read(max_bytes=MAX_SOCKET_READ_BYTES, deadline=nil)
48
+ data = super
49
+ @frame << data
50
+ result = []
51
+ while msg = @frame.next
52
+ result << msg
53
+ end
54
+ result.join
55
+ end
56
+
57
+ def read_line(deadline=nil)
58
+ data = super
59
+ @frame << data
60
+ result = []
61
+ while msg = @frame.next
62
+ result << msg
63
+ end
64
+ result.join
65
+ end
66
+
67
+ def write(data, deadline=nil)
68
+ raise HandshakeError, "Attempted to write to socket while WebSocket handshake is in progress" unless @handshaked
69
+
70
+ frame = ::WebSocket::Frame::Outgoing::Client.new(data: data, type: :binary, version: @handshake.version)
71
+ super frame.to_s
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,304 @@
1
+ module NATS
2
+ # class << self
3
+ def self.connect: (String?, Hash[Symbol, untyped]) -> NATS::Client
4
+ # end class << self
5
+
6
+ module Status
7
+ DISCONNECTED: Integer
8
+ CONNECTED: Integer
9
+ CLOSED: Integer
10
+ RECONNECTING: Integer
11
+ CONNECTING: Integer
12
+ DRAINING_SUBS: Integer
13
+ DRAINING_PUBS: Integer
14
+ end
15
+
16
+ class Client
17
+ include MonitorMixin
18
+ include Status
19
+
20
+ attr_reader status: Integer
21
+ attr_reader server_info: Hash[Symbol, untyped]
22
+ attr_reader server_pool: Array[untyped]
23
+ attr_reader options: Hash[Symbol, untyped]?
24
+ attr_reader connected_server: String?
25
+ attr_reader stats: Hash[Symbol, Integer]
26
+ attr_reader uri: String?
27
+ attr_reader subscription_executor: Concurrent::ThreadPoolExecutor?
28
+ attr_reader reloader: Proc
29
+
30
+ DEFAULT_PORT: Hash[Symbol, Integer]
31
+ DEFAULT_URI: String
32
+
33
+ CR_LF: '\r\n'
34
+ CR_LF_SIZE: Integer
35
+
36
+ PING_REQUEST: String
37
+ PONG_RESPONSE: String
38
+
39
+ NATS_HDR_LINE: String
40
+ STATUS_MSG_LEN: 3
41
+ STATUS_HDR: 'Status'
42
+ DESC_HDR: 'Description'
43
+ NATS_HDR_LINE_SIZE: Integer
44
+
45
+ SUB_OP: 'SUB'
46
+ EMPTY_MSG: ''
47
+
48
+ INSTANCES: ObjectSpace::WeakMap
49
+
50
+ @options: Hash[Symbol, untyped]
51
+
52
+ @io: NATS::IO::Socket?
53
+
54
+ @flush_queue: Thread::SizedQueue?
55
+ @pending_queue: Thread::SizedQueue?
56
+
57
+ @parser: NATS::Protocol::Parser
58
+
59
+ @flusher_thread: Thread?
60
+ @read_loop_thread: Thread?
61
+ @ping_interval_thread: Thread?
62
+ @subscription_executor: Concurrent::ThreadPoolExecutor?
63
+
64
+ @subs: Hash[Symbol, untyped]
65
+ @ssid: Integer
66
+
67
+ @pings_outstanding: Integer
68
+ @pongs_received: Integer
69
+ @pongs: Array[MonitorMixin::ConditionVariable]
70
+
71
+ @pending_size: Integer
72
+
73
+ @last_err: untyped
74
+
75
+ @err_cb: Proc
76
+ @close_cp: Proc
77
+ @disconnect_cb: Proc
78
+ @reconnect_cb: Proc
79
+
80
+ @tls: bool?
81
+
82
+ @hostname: String?
83
+ @single_url_connect_used: bool
84
+
85
+ @connect_called: bool
86
+
87
+ @resp_sub: NATS::Subscription?
88
+ @resp_map: Hash[String | Symbol, untyped]?
89
+ @resp_sub_prefix: String?
90
+ @nuid: NATS::NUID
91
+
92
+ @user_credentials: String?
93
+ @nkeys_seed: String?
94
+ @user_nkey_cb: Proc?
95
+ @user_jwt_cb: Proc?
96
+ @signature_cb: Proc?
97
+
98
+ @auth_token: String?
99
+
100
+ @inbox_prefix: String
101
+
102
+ @drain_t: Thread?
103
+
104
+ @reloader: Proc
105
+
106
+ def self.default_reloader: -> Proc
107
+
108
+ def connect: ((String | Hash[Symbol, untyped])?, Hash[Symbol, untyped]) -> self
109
+
110
+ def publish: (String, String, String?, **Hash[Symbol, untyped]) -> void
111
+
112
+ def publish_msg: (NATS::Msg) -> void
113
+
114
+ def subscribe: (String, Hash[Symbol, untyped]) ?{ (?(NATS::Msg | String), ?String, ?String, ?Hash[Symbol, untyped]) -> void } -> NATS::Subscription
115
+
116
+ def request: (String, ?String, **Hash[Symbol, untyped]) ?{ (?(NATS::Msg | String), ?String, ?String, ?Hash[Symbol, untyped]) -> void } -> NATS::Msg
117
+
118
+ def request_msg: (NATS::Msg, **Hash[Symbol, untyped]) -> NATS::Msg
119
+
120
+ def old_request: (String, ?String, **Hash[Symbol, untyped]) ?{ (?(NATS::Msg | String), ?String, ?String, ?Hash[Symbol, untyped]) -> void } -> NATS::Msg
121
+
122
+ def flush: (?Integer) -> void
123
+
124
+ alias servers server_pool
125
+
126
+ def discovered_servers: () -> Array[String]
127
+
128
+ def close: () -> void
129
+
130
+ def new_inbox: () -> String
131
+
132
+ def connected?: () -> bool
133
+
134
+ def connecting?: () -> bool
135
+
136
+ def reconnecting?: () -> bool
137
+
138
+ def closed?: () -> bool
139
+
140
+ def draining?: () -> bool
141
+
142
+ def on_error: () { (?self, ?untyped, ?NATS::Subscription) -> void } -> void
143
+
144
+ def on_disconnect: () { (?untyped) -> void } -> void
145
+
146
+ def on_reconnect: () { () -> void } -> void
147
+
148
+ def on_close: () { () -> void } -> void
149
+
150
+ def last_error: () -> untyped
151
+
152
+ def drain: () -> void
153
+
154
+ def jetstream: (**Hash[Symbol, untyped]) -> NATS::JetStream
155
+ alias JetStream jetstream
156
+ alias jsm jetstream
157
+
158
+ private
159
+
160
+ def validate_settings!: () -> void
161
+
162
+ def process_info: (String) -> Hash[Symbol, untyped]
163
+
164
+ def process_hdr: (String) -> Hash[String, untyped]?
165
+
166
+ def process_pong: () -> void
167
+
168
+ def process_ping: () -> void
169
+
170
+ def process_err: (String) -> void
171
+
172
+ def process_msg: (String, String, String, String, String) -> void
173
+
174
+ def select_next_error: () -> untyped
175
+
176
+ def server_using_secure_connection?: () -> bool
177
+
178
+ def client_using_secure_connection?: () -> bool
179
+
180
+ def single_url_connect_used?: () -> bool
181
+
182
+ def send_command: (String) -> void
183
+
184
+ def unsubscribe: (NATS::Subscription, Integer?) -> void
185
+
186
+ def drain_sub: (NATS::Subscription) -> void
187
+
188
+ def do_drain: () -> void
189
+
190
+ def send_flush_queue: (Symbol) -> void
191
+
192
+ def delete_sid: (Symbol) -> void
193
+
194
+ def err_cb_call: (self, untyped, NATS::Subscription) -> void
195
+
196
+ def auth_connection?: () -> bool
197
+
198
+ def connect_command: () -> String
199
+
200
+ def process_op_error: (untyped) -> void
201
+
202
+ def read_loop: () -> void
203
+
204
+ def flusher_loop: () -> void
205
+
206
+ def force_flush!: () -> void
207
+
208
+ def ping_interval_loop: () -> void
209
+
210
+ def process_connect_init: () -> void
211
+
212
+ def attempt_reconnect: () -> void
213
+
214
+ def close_connection: (Integer, bool) -> void
215
+
216
+ def start_threads!: () -> void
217
+
218
+ def start_resp_mux_sub!: () -> void
219
+
220
+ def can_reuse_server?: (Hash[Symbol, untyped]) -> bool
221
+
222
+ def should_delay_connect?: () -> bool
223
+
224
+ def should_not_reconnect?: () -> bool
225
+
226
+ def should_reconnect?: () -> bool
227
+
228
+ def create_socket: () -> NATS::IO::Socket
229
+
230
+ def setup_nkeys_connect: () -> void
231
+
232
+ def signature_cb_for_nkey_file: (String) -> Proc
233
+
234
+ def nkey_cb_for_nkey_file: (String) -> Proc
235
+
236
+ def jwt_cb_for_creds_file: (String) -> Proc
237
+
238
+ def signature_cb_for_creds_file: (String) -> Proc
239
+
240
+ def process_uri: (String) -> Array[URI::Generic]
241
+ end
242
+
243
+ module IO
244
+ include Status
245
+
246
+ Client: NATS::Client
247
+
248
+ MAX_RECONNECT_ATTEMPTS: 10
249
+ RECONNECT_TIME_WAIT: 2
250
+
251
+ MAX_PENDING_SIZE: 32768
252
+
253
+ MAX_FLUSH_KICK_SIZE: 1024
254
+
255
+ MAX_SOCKET_READ_BYTES: 32768
256
+
257
+ DEFAULT_PING_INTERVAL: 120
258
+ DEFAULT_PING_MAX: 2
259
+
260
+ DEFAULT_CONNECT_TIMEOUT: 2
261
+ DEFAULT_READ_WRITE_TIMEOUT: 2
262
+ DEFAULT_DRAIN_TIMEOUT: 30
263
+
264
+ DEFAULT_SUB_PENDING_MSGS_LIMIT: 65536
265
+ DEFAULT_SUB_PENDING_BYTES_LIMIT: Integer
266
+
267
+ class Socket
268
+ attr_accessor socket: ::Socket?
269
+
270
+ @uri: URI::Generic
271
+ @connect_timeout: Numeric
272
+ @write_timeout: Numeric
273
+ @read_timeout: Numeric
274
+
275
+ def connect: () -> void
276
+
277
+ def read_line: (Numeric?) -> untyped
278
+
279
+ def read: (Integer, Numeric?) -> untyped
280
+
281
+ def write: (String, Numeric?) -> void
282
+
283
+ def close: () -> void
284
+
285
+ def closed?: () -> bool
286
+
287
+ private
288
+
289
+ def connect_addrinfo: (String | Integer, Integer, Numeric) -> ::Socket
290
+ end
291
+ end
292
+
293
+ NANOSECONDS: 1_000_000_000
294
+
295
+ class MonotonicTime
296
+ # class << self
297
+ def self.now: () -> Float
298
+
299
+ def self.with_nats_timeout: (Float) -> Float
300
+
301
+ def self.since: (Float) -> Float
302
+ # end class << self
303
+ end
304
+ end