nats-pure 0.4.0 → 0.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/lib/nats/io/client.rb +120 -4
- data/lib/nats/io/parser.rb +14 -0
- data/lib/nats/io/version.rb +15 -1
- data/lib/nats/nuid.rb +81 -0
- metadata +5 -4
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 741d87f63f2851dc25639453f9cd5ed68b3e2bfb66f45f1b5fe6caa9b3e352dd
         | 
| 4 | 
            +
              data.tar.gz: 1af44d28a31788e37fbb50d14f966ff30805ee42614ae37a7ab3599edd0de4f0
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 432d3b3cf28752ec19c6278763ec5e1ef5992ee9d57796aeadb41b978028b3700c699795134f46297c982d9fc98fc3979d0760842f74fb528977e62b66431c9c
         | 
| 7 | 
            +
              data.tar.gz: 758a3b3deb4c2b14198bca42b647d2b11726c08d7150a914a8835a64fa6720d57d28c2207ddcd6ad40995427902ab1afd6705f2ab4c4ea1adbe9e131ccc1ea32
         | 
    
        data/lib/nats/io/client.rb
    CHANGED
    
    | @@ -1,5 +1,20 @@ | |
| 1 | 
            +
            # Copyright 2016-2018 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 | 
            +
             | 
| 1 15 | 
             
            require 'nats/io/parser'
         | 
| 2 16 | 
             
            require 'nats/io/version'
         | 
| 17 | 
            +
            require 'nats/nuid'
         | 
| 3 18 | 
             
            require 'thread'
         | 
| 4 19 | 
             
            require 'socket'
         | 
| 5 20 | 
             
            require 'json'
         | 
| @@ -159,13 +174,20 @@ module NATS | |
| 159 174 | 
             
                    # Hostname of current server; used for when TLS host
         | 
| 160 175 | 
             
                    # verification is enabled.
         | 
| 161 176 | 
             
                    @hostname = nil
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                    # New style request/response implementation.
         | 
| 179 | 
            +
                    @resp_sub = nil
         | 
| 180 | 
            +
                    @resp_map = nil
         | 
| 181 | 
            +
                    @resp_sub_prefix = nil
         | 
| 182 | 
            +
                    @nuid = NATS::NUID.new
         | 
| 162 183 | 
             
                  end
         | 
| 163 184 |  | 
| 164 | 
            -
                  # Establishes connection to NATS
         | 
| 185 | 
            +
                  # Establishes connection to NATS.
         | 
| 165 186 | 
             
                  def connect(opts={})
         | 
| 166 187 | 
             
                    opts[:verbose] = false if opts[:verbose].nil?
         | 
| 167 188 | 
             
                    opts[:pedantic] = false if opts[:pedantic].nil?
         | 
| 168 189 | 
             
                    opts[:reconnect] = true if opts[:reconnect].nil?
         | 
| 190 | 
            +
                    opts[:old_style_request] = false if opts[:old_style_request].nil?
         | 
| 169 191 | 
             
                    opts[:reconnect_time_wait] = RECONNECT_TIME_WAIT if opts[:reconnect_time_wait].nil?
         | 
| 170 192 | 
             
                    opts[:max_reconnect_attempts] = MAX_RECONNECT_ATTEMPTS if opts[:max_reconnect_attempts].nil?
         | 
| 171 193 | 
             
                    opts[:ping_interval] = DEFAULT_PING_INTERVAL if opts[:ping_interval].nil?
         | 
| @@ -198,6 +220,12 @@ module NATS | |
| 198 220 | 
             
                      }
         | 
| 199 221 | 
             
                    end
         | 
| 200 222 |  | 
| 223 | 
            +
                    if @options[:old_style_request]
         | 
| 224 | 
            +
                      # Replace for this instance the implementation
         | 
| 225 | 
            +
                      # of request to use the old_request style.
         | 
| 226 | 
            +
                      class << self; alias_method :request, :old_request; end
         | 
| 227 | 
            +
                    end
         | 
| 228 | 
            +
             | 
| 201 229 | 
             
                    # Check for TLS usage
         | 
| 202 230 | 
             
                    @tls = @options[:tls]
         | 
| 203 231 |  | 
| @@ -344,11 +372,58 @@ module NATS | |
| 344 372 | 
             
                    sid
         | 
| 345 373 | 
             
                  end
         | 
| 346 374 |  | 
| 347 | 
            -
                  # Sends a request expecting a single response  | 
| 348 | 
            -
                  #  | 
| 375 | 
            +
                  # Sends a request using expecting a single response using a
         | 
| 376 | 
            +
                  # single subscription per connection for receiving the responses.
         | 
| 377 | 
            +
                  # It times out in case the request is not retrieved within the
         | 
| 378 | 
            +
                  # specified deadline.
         | 
| 349 379 | 
             
                  # If given a callback, then the request happens asynchronously.
         | 
| 350 380 | 
             
                  def request(subject, payload, opts={}, &blk)
         | 
| 351 381 | 
             
                    return unless subject
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                    # If a block was given then fallback to method using auto unsubscribe.
         | 
| 384 | 
            +
                    return old_request(subject, payload, opts, &blk) if blk
         | 
| 385 | 
            +
             | 
| 386 | 
            +
                    token = nil
         | 
| 387 | 
            +
                    inbox = nil
         | 
| 388 | 
            +
                    future = nil
         | 
| 389 | 
            +
                    response = nil
         | 
| 390 | 
            +
                    timeout = opts[:timeout] ||= 0.5
         | 
| 391 | 
            +
                    synchronize do
         | 
| 392 | 
            +
                      start_resp_mux_sub! unless @resp_sub_prefix
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                      # Create token for this request.
         | 
| 395 | 
            +
                      token = @nuid.next
         | 
| 396 | 
            +
                      inbox = "#{@resp_sub_prefix}.#{token}"
         | 
| 397 | 
            +
             | 
| 398 | 
            +
                      # Create the a future for the request that will
         | 
| 399 | 
            +
                      # get signaled when it receives the request.
         | 
| 400 | 
            +
                      future = @resp_sub.new_cond
         | 
| 401 | 
            +
                      @resp_map[token][:future] = future
         | 
| 402 | 
            +
                    end
         | 
| 403 | 
            +
             | 
| 404 | 
            +
                    # Publish request and wait for reply.
         | 
| 405 | 
            +
                    publish(subject, payload, inbox)
         | 
| 406 | 
            +
                    with_nats_timeout(timeout) do
         | 
| 407 | 
            +
                      @resp_sub.synchronize do
         | 
| 408 | 
            +
                        future.wait(timeout)
         | 
| 409 | 
            +
                      end
         | 
| 410 | 
            +
                    end
         | 
| 411 | 
            +
             | 
| 412 | 
            +
                    # Check if there is a response already
         | 
| 413 | 
            +
                    synchronize do
         | 
| 414 | 
            +
                      result = @resp_map[token]
         | 
| 415 | 
            +
                      response = result[:response]
         | 
| 416 | 
            +
                    end
         | 
| 417 | 
            +
             | 
| 418 | 
            +
                    response
         | 
| 419 | 
            +
                  end
         | 
| 420 | 
            +
             | 
| 421 | 
            +
                  # Sends a request creating an ephemeral subscription for the request,
         | 
| 422 | 
            +
                  # expecting a single response or raising a timeout in case the request
         | 
| 423 | 
            +
                  # is not retrieved within the specified deadline.
         | 
| 424 | 
            +
                  # If given a callback, then the request happens asynchronously.
         | 
| 425 | 
            +
                  def old_request(subject, payload, opts={}, &blk)
         | 
| 426 | 
            +
                    return unless subject
         | 
| 352 427 | 
             
                    inbox = new_inbox
         | 
| 353 428 |  | 
| 354 429 | 
             
                    # If a callback was passed, then have it process
         | 
| @@ -520,7 +595,7 @@ module NATS | |
| 520 595 | 
             
                        future.signal
         | 
| 521 596 |  | 
| 522 597 | 
             
                        return
         | 
| 523 | 
            -
                      elsif sub. | 
| 598 | 
            +
                      elsif sub.pending_queue
         | 
| 524 599 | 
             
                        # Async subscribers use a sized queue for processing
         | 
| 525 600 | 
             
                        # and should be able to consume messages in parallel.
         | 
| 526 601 | 
             
                        if sub.pending_queue.size >= sub.pending_msgs_limit \
         | 
| @@ -1093,6 +1168,47 @@ module NATS | |
| 1093 1168 | 
             
                    @ping_interval_thread.abort_on_exception = true
         | 
| 1094 1169 | 
             
                  end
         | 
| 1095 1170 |  | 
| 1171 | 
            +
                  # Prepares requests subscription that handles the responses
         | 
| 1172 | 
            +
                  # for the new style request response.
         | 
| 1173 | 
            +
                  def start_resp_mux_sub!
         | 
| 1174 | 
            +
                    @resp_sub_prefix = "_INBOX.#{@nuid.next}"
         | 
| 1175 | 
            +
                    @resp_map = Hash.new { |h,k| h[k] = { }}
         | 
| 1176 | 
            +
             | 
| 1177 | 
            +
                    @resp_sub = Subscription.new
         | 
| 1178 | 
            +
                    @resp_sub.subject = "#{@resp_sub_prefix}.*"
         | 
| 1179 | 
            +
                    @resp_sub.received = 0
         | 
| 1180 | 
            +
             | 
| 1181 | 
            +
                    # FIXME: Allow setting pending limits for responses mux subscription.
         | 
| 1182 | 
            +
                    @resp_sub.pending_msgs_limit = DEFAULT_SUB_PENDING_MSGS_LIMIT
         | 
| 1183 | 
            +
                    @resp_sub.pending_bytes_limit = DEFAULT_SUB_PENDING_BYTES_LIMIT
         | 
| 1184 | 
            +
                    @resp_sub.pending_queue = SizedQueue.new(@resp_sub.pending_msgs_limit)
         | 
| 1185 | 
            +
                    @resp_sub.wait_for_msgs_t = Thread.new do
         | 
| 1186 | 
            +
                      loop do
         | 
| 1187 | 
            +
                        msg = @resp_sub.pending_queue.pop
         | 
| 1188 | 
            +
                        @resp_sub.pending_size -= msg.data.size
         | 
| 1189 | 
            +
             | 
| 1190 | 
            +
                        # Pick the token and signal the request under the mutex
         | 
| 1191 | 
            +
                        # from the subscription itself.
         | 
| 1192 | 
            +
                        token = msg.subject.split('.').last
         | 
| 1193 | 
            +
                        future = nil
         | 
| 1194 | 
            +
                        synchronize do
         | 
| 1195 | 
            +
                          future = @resp_map[token][:future]
         | 
| 1196 | 
            +
                          @resp_map[token][:response] = msg
         | 
| 1197 | 
            +
                        end
         | 
| 1198 | 
            +
             | 
| 1199 | 
            +
                        # Signal back that the response has arrived.
         | 
| 1200 | 
            +
                        @resp_sub.synchronize do
         | 
| 1201 | 
            +
                          future.signal
         | 
| 1202 | 
            +
                        end
         | 
| 1203 | 
            +
                      end
         | 
| 1204 | 
            +
                    end
         | 
| 1205 | 
            +
             | 
| 1206 | 
            +
                    sid = (@ssid += 1)
         | 
| 1207 | 
            +
                    @subs[sid] = @resp_sub
         | 
| 1208 | 
            +
                    send_command("SUB #{@resp_sub.subject} #{sid}#{CR_LF}")
         | 
| 1209 | 
            +
                    @flush_queue << :sub
         | 
| 1210 | 
            +
                  end
         | 
| 1211 | 
            +
             | 
| 1096 1212 | 
             
                  def can_reuse_server?(server)
         | 
| 1097 1213 | 
             
                    return false if server.nil?
         | 
| 1098 1214 |  | 
    
        data/lib/nats/io/parser.rb
    CHANGED
    
    | @@ -1,3 +1,17 @@ | |
| 1 | 
            +
            # Copyright 2016-2018 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 | 
            +
             | 
| 1 15 | 
             
            module NATS
         | 
| 2 16 | 
             
              module Protocol
         | 
| 3 17 |  | 
    
        data/lib/nats/io/version.rb
    CHANGED
    
    | @@ -1,7 +1,21 @@ | |
| 1 | 
            +
            # Copyright 2016-2018 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 | 
            +
             | 
| 1 15 | 
             
            module NATS
         | 
| 2 16 | 
             
              module IO
         | 
| 3 17 | 
             
                # NOTE: These are all announced to the server on CONNECT
         | 
| 4 | 
            -
                VERSION  = "0. | 
| 18 | 
            +
                VERSION  = "0.5.0"
         | 
| 5 19 | 
             
                LANG     = "#{RUBY_ENGINE}2".freeze
         | 
| 6 20 | 
             
                PROTOCOL = 1
         | 
| 7 21 | 
             
              end
         | 
    
        data/lib/nats/nuid.rb
    ADDED
    
    | @@ -0,0 +1,81 @@ | |
| 1 | 
            +
            # Copyright 2016-2018 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 'securerandom'
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            module NATS
         | 
| 17 | 
            +
              class NUID
         | 
| 18 | 
            +
                DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
         | 
| 19 | 
            +
                BASE          = 62
         | 
| 20 | 
            +
                PREFIX_LENGTH = 12
         | 
| 21 | 
            +
                SEQ_LENGTH    = 10
         | 
| 22 | 
            +
                TOTAL_LENGTH  = PREFIX_LENGTH + SEQ_LENGTH
         | 
| 23 | 
            +
                MAX_SEQ       = BASE**10
         | 
| 24 | 
            +
                MIN_INC       = 33
         | 
| 25 | 
            +
                MAX_INC       = 333
         | 
| 26 | 
            +
                INC = MAX_INC - MIN_INC
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def initialize
         | 
| 29 | 
            +
                  @prand    = Random.new
         | 
| 30 | 
            +
                  @seq      = @prand.rand(MAX_SEQ)
         | 
| 31 | 
            +
                  @inc      = MIN_INC + @prand.rand(INC)
         | 
| 32 | 
            +
                  @prefix   = ''
         | 
| 33 | 
            +
                  randomize_prefix!
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def next
         | 
| 37 | 
            +
                  @seq += @inc
         | 
| 38 | 
            +
                  if @seq >= MAX_SEQ
         | 
| 39 | 
            +
                    randomize_prefix!
         | 
| 40 | 
            +
                    reset_sequential!
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                  l = @seq
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  # Do this inline 10 times to avoid even more extra allocs,
         | 
| 45 | 
            +
                  # then use string interpolation of everything which works
         | 
| 46 | 
            +
                  # faster for doing concat.
         | 
| 47 | 
            +
                  s_10 = DIGITS[l % BASE];
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  # Ugly, but parallel assignment is slightly faster here...
         | 
| 50 | 
            +
                  s_09, s_08, s_07, s_06, s_05, s_04, s_03, s_02, s_01 = \
         | 
| 51 | 
            +
                  (l /= BASE; DIGITS[l % BASE]), (l /= BASE; DIGITS[l % BASE]), (l /= BASE; DIGITS[l % BASE]),\
         | 
| 52 | 
            +
                  (l /= BASE; DIGITS[l % BASE]), (l /= BASE; DIGITS[l % BASE]), (l /= BASE; DIGITS[l % BASE]),\
         | 
| 53 | 
            +
                  (l /= BASE; DIGITS[l % BASE]), (l /= BASE; DIGITS[l % BASE]), (l /= BASE; DIGITS[l % BASE])
         | 
| 54 | 
            +
                  "#{@prefix}#{s_01}#{s_02}#{s_03}#{s_04}#{s_05}#{s_06}#{s_07}#{s_08}#{s_09}#{s_10}"
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                def randomize_prefix!
         | 
| 58 | 
            +
                  @prefix = \
         | 
| 59 | 
            +
                  SecureRandom.random_bytes(PREFIX_LENGTH).each_byte
         | 
| 60 | 
            +
                    .reduce('') do |prefix, n|
         | 
| 61 | 
            +
                    prefix << DIGITS[n % BASE]
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                private
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def reset_sequential!
         | 
| 68 | 
            +
                  @seq = @prand.rand(MAX_SEQ)
         | 
| 69 | 
            +
                  @inc = MIN_INC + @prand.rand(INC)
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                class << self
         | 
| 73 | 
            +
                  @@nuid = NUID.new.extend(MonitorMixin)
         | 
| 74 | 
            +
                  def next
         | 
| 75 | 
            +
                    @@nuid.synchronize do
         | 
| 76 | 
            +
                      @@nuid.next
         | 
| 77 | 
            +
                    end
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
              end
         | 
| 81 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,19 +1,19 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: nats-pure
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.5.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: 2018- | 
| 11 | 
            +
            date: 2018-04-04 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies: []
         | 
| 13 13 | 
             
            description: NATS is an open-source, high-performance, lightweight cloud messaging
         | 
| 14 14 | 
             
              system.
         | 
| 15 15 | 
             
            email:
         | 
| 16 | 
            -
            - wally@ | 
| 16 | 
            +
            - wally@synadia.com
         | 
| 17 17 | 
             
            executables: []
         | 
| 18 18 | 
             
            extensions: []
         | 
| 19 19 | 
             
            extra_rdoc_files: []
         | 
| @@ -21,9 +21,10 @@ files: | |
| 21 21 | 
             
            - lib/nats/io/client.rb
         | 
| 22 22 | 
             
            - lib/nats/io/parser.rb
         | 
| 23 23 | 
             
            - lib/nats/io/version.rb
         | 
| 24 | 
            +
            - lib/nats/nuid.rb
         | 
| 24 25 | 
             
            homepage: https://nats.io
         | 
| 25 26 | 
             
            licenses:
         | 
| 26 | 
            -
            -  | 
| 27 | 
            +
            - Apache-2.0
         | 
| 27 28 | 
             
            metadata: {}
         | 
| 28 29 | 
             
            post_install_message: 
         | 
| 29 30 | 
             
            rdoc_options: []
         |