jrpc 0.4.6 → 1.0.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/jrpc.gemspec +1 -1
- data/lib/jrpc/base_client.rb +47 -19
- data/lib/jrpc/tcp_client.rb +39 -23
- data/lib/jrpc/version.rb +1 -1
- metadata +4 -10
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 88f3c2e9907a01e2628d9eb41bb96be8d683ab40
         | 
| 4 | 
            +
              data.tar.gz: 8543544144a943094699050800dc5645402aa954
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 8b4906aa2277f8e6dae407f222a206071cd8fe2979c869a0808945befe5093e44957f20ea55a8c78248777304198035c2574f08f18924ecd23d673abc3393e39
         | 
| 7 | 
            +
              data.tar.gz: 3b43159a29ebf248714acede8b4a20cf83f629f14291b92d557da2c6ef5f846462feb62d1af98ba6436f4a1c0b676e043234a85ca970e8ed2ee19248efc8e912
         | 
    
        data/jrpc.gemspec
    CHANGED
    
    | @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| | |
| 18 18 | 
             
              spec.require_paths = ['lib']
         | 
| 19 19 |  | 
| 20 20 | 
             
              spec.add_dependency 'netstring', '~> 0'
         | 
| 21 | 
            -
              spec.add_dependency 'net_tcp_client', '~>  | 
| 21 | 
            +
              spec.add_dependency 'net_tcp_client', '~> 2.0'
         | 
| 22 22 | 
             
              spec.add_dependency 'oj', '~> 2.0'
         | 
| 23 23 |  | 
| 24 24 | 
             
              spec.add_development_dependency 'bundler', '~> 1.10'
         | 
    
        data/lib/jrpc/base_client.rb
    CHANGED
    
    | @@ -7,6 +7,7 @@ module JRPC | |
| 7 7 | 
             
                attr_reader :uri, :options
         | 
| 8 8 |  | 
| 9 9 | 
             
                ID_CHARACTERS = (('a'..'z').to_a + ('0'..'9').to_a + ('A'..'Z').to_a).freeze
         | 
| 10 | 
            +
                REQUEST_TYPES = [:request, :notification].freeze
         | 
| 10 11 |  | 
| 11 12 | 
             
                def initialize(uri, options)
         | 
| 12 13 | 
             
                  @uri = uri
         | 
| @@ -17,31 +18,58 @@ module JRPC | |
| 17 18 | 
             
                  invoke_request(method, *params)
         | 
| 18 19 | 
             
                end
         | 
| 19 20 |  | 
| 20 | 
            -
                def  | 
| 21 | 
            -
                   | 
| 22 | 
            -
                   | 
| 23 | 
            -
                   | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 21 | 
            +
                def perform_request(method, params: nil, type: :request, read_timeout: nil, write_timeout: nil)
         | 
| 22 | 
            +
                  validate_request(params, type)
         | 
| 23 | 
            +
                  request = create_message(method.to_s, params)
         | 
| 24 | 
            +
                  if type == :request
         | 
| 25 | 
            +
                    id = generate_id
         | 
| 26 | 
            +
                    request['id'] = id
         | 
| 27 | 
            +
                    response = send_command serialize_request(request), read_timeout: read_timeout, write_timeout: write_timeout
         | 
| 28 | 
            +
                    response = deserialize_response(response)
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    validate_response(response, id)
         | 
| 31 | 
            +
                    parse_error(response['error']) if response.has_key?('error')
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    response['result']
         | 
| 34 | 
            +
                  else
         | 
| 35 | 
            +
                    send_notification serialize_request(request), write_timeout: write_timeout
         | 
| 36 | 
            +
                    nil
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                end
         | 
| 30 39 |  | 
| 31 | 
            -
             | 
| 40 | 
            +
                def invoke_request(method, *params)
         | 
| 41 | 
            +
                  warn '[DEPRECATION] `invoke_request` is deprecated. Please use `perform_request` instead.'
         | 
| 42 | 
            +
                  params = nil if params.empty?
         | 
| 43 | 
            +
                  perform_request(method, params: params)
         | 
| 32 44 | 
             
                end
         | 
| 33 45 |  | 
| 34 46 | 
             
                def invoke_notification(method, *params)
         | 
| 35 | 
            -
                   | 
| 36 | 
            -
                  nil
         | 
| 47 | 
            +
                  warn '[DEPRECATION] `invoke_request` is deprecated. Please use `perform_request` instead.'
         | 
| 48 | 
            +
                  params = nil if params.empty?
         | 
| 49 | 
            +
                  perform_request(method, params: params, type: :notification)
         | 
| 37 50 | 
             
                end
         | 
| 38 51 |  | 
| 39 52 | 
             
                private
         | 
| 40 53 |  | 
| 54 | 
            +
                def serialize_request(request)
         | 
| 55 | 
            +
                  Oj.dump(request, mode: :compat)
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def deserialize_response(response)
         | 
| 59 | 
            +
                  Oj.load(response)
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 41 62 | 
             
                def validate_response(response, id)
         | 
| 42 | 
            -
                  raise ClientError | 
| 43 | 
            -
                  raise ClientError | 
| 44 | 
            -
                   | 
| 63 | 
            +
                  raise ClientError, 'Wrong response structure' unless response.is_a?(Hash)
         | 
| 64 | 
            +
                  raise ClientError, 'Wrong version' if response['jsonrpc'] != JRPC::JSON_RPC_VERSION
         | 
| 65 | 
            +
                  if id != response['id']
         | 
| 66 | 
            +
                    raise ClientError, "ID response mismatch. expected #{id.inspect} got #{response['id'].inspect}"
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                def validate_request(params, type)
         | 
| 71 | 
            +
                  raise ClientError, 'invalid type' unless REQUEST_TYPES.include?(type)
         | 
| 72 | 
            +
                  raise ClientError, 'invalid params' if !params.nil? && !params.is_a?(Array) && !params.is_a?(Hash)
         | 
| 45 73 | 
             
                end
         | 
| 46 74 |  | 
| 47 75 | 
             
                def parse_error(error)
         | 
| @@ -63,11 +91,11 @@ module JRPC | |
| 63 91 | 
             
                  end
         | 
| 64 92 | 
             
                end
         | 
| 65 93 |  | 
| 66 | 
            -
                def send_command(json)
         | 
| 94 | 
            +
                def send_command(json, options={})
         | 
| 67 95 | 
             
                  raise NotImplementedError
         | 
| 68 96 | 
             
                end
         | 
| 69 97 |  | 
| 70 | 
            -
                def send_notification(json)
         | 
| 98 | 
            +
                def send_notification(json, options={})
         | 
| 71 99 | 
             
                  raise NotImplementedError
         | 
| 72 100 | 
             
                end
         | 
| 73 101 |  | 
| @@ -81,7 +109,7 @@ module JRPC | |
| 81 109 | 
             
                      'jsonrpc' => JSON_RPC_VERSION,
         | 
| 82 110 | 
             
                      'method' => method
         | 
| 83 111 | 
             
                  }
         | 
| 84 | 
            -
                  message['params'] = params unless params. | 
| 112 | 
            +
                  message['params'] = params unless params.nil?
         | 
| 85 113 | 
             
                  message
         | 
| 86 114 | 
             
                end
         | 
| 87 115 | 
             
              end
         | 
    
        data/lib/jrpc/tcp_client.rb
    CHANGED
    
    | @@ -14,12 +14,18 @@ module JRPC | |
| 14 14 | 
             
                  super
         | 
| 15 15 | 
             
                  @logger = @options.delete(:logger) || Logger.new($null)
         | 
| 16 16 | 
             
                  @namespace = @options.delete(:namespace).to_s
         | 
| 17 | 
            -
             | 
| 17 | 
            +
             | 
| 18 | 
            +
                  timeout = @options.fetch(:timeout, 5)
         | 
| 19 | 
            +
                  connect_timeout = @options.fetch(:connect_timeout, timeout)
         | 
| 20 | 
            +
                  read_timeout = @options.fetch(:read_timeout, timeout)
         | 
| 21 | 
            +
                  write_timeout = @options.fetch(:write_timeout, nil) # default 60
         | 
| 22 | 
            +
                  connect_retry_count = @options.fetch(:connect_retry_count, nil) # default 10
         | 
| 18 23 |  | 
| 19 24 | 
             
                  @transport = Net::TCPClient.new server: @uri,
         | 
| 20 | 
            -
                                               connect_retry_count:  | 
| 21 | 
            -
                                               connect_timeout:  | 
| 22 | 
            -
                                               read_timeout:  | 
| 25 | 
            +
                                               connect_retry_count: connect_retry_count,
         | 
| 26 | 
            +
                                               connect_timeout: connect_timeout,
         | 
| 27 | 
            +
                                               read_timeout: read_timeout,
         | 
| 28 | 
            +
                                               write_timeout: write_timeout,
         | 
| 23 29 | 
             
                                               buffered: false # recommended for RPC
         | 
| 24 30 | 
             
                rescue ::SocketError
         | 
| 25 31 | 
             
                  raise ConnectionError, "Can't connect to #{@uri}"
         | 
| @@ -27,48 +33,58 @@ module JRPC | |
| 27 33 |  | 
| 28 34 | 
             
                private
         | 
| 29 35 |  | 
| 30 | 
            -
                def send_command(request)
         | 
| 36 | 
            +
                def send_command(request, options={})
         | 
| 37 | 
            +
                  read_timeout = options.fetch(:read_timeout)
         | 
| 38 | 
            +
                  write_timeout = options.fetch(:write_timeout)
         | 
| 31 39 | 
             
                  response = nil
         | 
| 32 40 | 
             
                  t = Benchmark.realtime do
         | 
| 33 | 
            -
                    logger.debug "Request address: #{uri}"
         | 
| 34 | 
            -
                    logger.debug "Request message: #{Utils.truncate(request, MAX_LOGGED_MESSAGE_LENGTH)}"
         | 
| 35 | 
            -
                     | 
| 36 | 
            -
                     | 
| 41 | 
            +
                    logger.debug { "Request address: #{uri}" }
         | 
| 42 | 
            +
                    logger.debug { "Request message: #{Utils.truncate(request, MAX_LOGGED_MESSAGE_LENGTH)}" }
         | 
| 43 | 
            +
                    logger.debug { "Request read_timeout: #{read_timeout}" }
         | 
| 44 | 
            +
                    logger.debug { "Request write_timeout: #{write_timeout}" }
         | 
| 45 | 
            +
                    send_request(request, write_timeout)
         | 
| 46 | 
            +
                    response = receive_response(read_timeout)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                  logger.debug do
         | 
| 49 | 
            +
                    "(#{'%.2f' % (t * 1000)}ms) Response message: #{Utils.truncate(response, MAX_LOGGED_MESSAGE_LENGTH)}"
         | 
| 37 50 | 
             
                  end
         | 
| 38 | 
            -
                  logger.debug "(#{'%.2f' % (t * 1000)}ms) Response message: #{Utils.truncate(response, MAX_LOGGED_MESSAGE_LENGTH)}"
         | 
| 39 51 | 
             
                  response
         | 
| 40 52 | 
             
                end
         | 
| 41 53 |  | 
| 42 | 
            -
                def send_notification(request)
         | 
| 43 | 
            -
                   | 
| 44 | 
            -
                  logger.debug "Request  | 
| 45 | 
            -
                   | 
| 46 | 
            -
                  logger.debug  | 
| 54 | 
            +
                def send_notification(request, options={})
         | 
| 55 | 
            +
                  write_timeout = options.fetch(:write_timeout)
         | 
| 56 | 
            +
                  logger.debug { "Request address: #{uri}" }
         | 
| 57 | 
            +
                  logger.debug { "Request message: #{Utils.truncate(request, MAX_LOGGED_MESSAGE_LENGTH)}" }
         | 
| 58 | 
            +
                  logger.debug { "Request write_timeout: #{write_timeout}" }
         | 
| 59 | 
            +
                  send_request(request, write_timeout)
         | 
| 60 | 
            +
                  logger.debug { 'No response required' }
         | 
| 47 61 | 
             
                end
         | 
| 48 62 |  | 
| 49 63 | 
             
                def create_message(method, params)
         | 
| 50 64 | 
             
                  super("#{namespace}#{method}", params)
         | 
| 51 65 | 
             
                end
         | 
| 52 66 |  | 
| 53 | 
            -
                def send_request(request)
         | 
| 54 | 
            -
                  @transport. | 
| 67 | 
            +
                def send_request(request, timeout)
         | 
| 68 | 
            +
                  timeout ||= @transport.write_timeout
         | 
| 69 | 
            +
                  @transport.write Netstring.dump(request.to_s), timeout
         | 
| 55 70 | 
             
                rescue ::SocketError
         | 
| 56 71 | 
             
                  raise ConnectionError, "Can't send request to #{uri}"
         | 
| 57 72 | 
             
                end
         | 
| 58 73 |  | 
| 59 | 
            -
                def receive_response
         | 
| 60 | 
            -
                   | 
| 61 | 
            -
                   | 
| 74 | 
            +
                def receive_response(timeout)
         | 
| 75 | 
            +
                  timeout ||= @transport.read_timeout
         | 
| 76 | 
            +
                  length = get_msg_length(timeout)
         | 
| 77 | 
            +
                  response = @transport.read(length+1, nil, timeout)
         | 
| 62 78 | 
             
                  raise ClientError.new('invalid response. missed comma as terminator') if response[-1] != ','
         | 
| 63 79 | 
             
                  response.chomp(',')
         | 
| 64 80 | 
             
                rescue ::SocketError
         | 
| 65 81 | 
             
                  raise ConnectionError, "Can't receive response from #{uri}"
         | 
| 66 82 | 
             
                end
         | 
| 67 83 |  | 
| 68 | 
            -
                def get_msg_length
         | 
| 84 | 
            +
                def get_msg_length(timeout)
         | 
| 69 85 | 
             
                  length = ''
         | 
| 70 86 | 
             
                  while true do
         | 
| 71 | 
            -
                    character = @transport.read(1)
         | 
| 87 | 
            +
                    character = @transport.read(1, nil, timeout)
         | 
| 72 88 | 
             
                    break if character == ':'
         | 
| 73 89 | 
             
                    length += character
         | 
| 74 90 | 
             
                  end
         | 
| @@ -77,4 +93,4 @@ module JRPC | |
| 77 93 | 
             
                end
         | 
| 78 94 |  | 
| 79 95 | 
             
              end
         | 
| 80 | 
            -
            end
         | 
| 96 | 
            +
            end
         | 
    
        data/lib/jrpc/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: jrpc
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 1.0.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Denis Talakevich
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2017-08-30 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: netstring
         | 
| @@ -30,20 +30,14 @@ dependencies: | |
| 30 30 | 
             
                requirements:
         | 
| 31 31 | 
             
                - - "~>"
         | 
| 32 32 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            -
                    version: ' | 
| 34 | 
            -
                - - ">="
         | 
| 35 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 36 | 
            -
                    version: 1.0.2
         | 
| 33 | 
            +
                    version: '2.0'
         | 
| 37 34 | 
             
              type: :runtime
         | 
| 38 35 | 
             
              prerelease: false
         | 
| 39 36 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 40 37 | 
             
                requirements:
         | 
| 41 38 | 
             
                - - "~>"
         | 
| 42 39 | 
             
                  - !ruby/object:Gem::Version
         | 
| 43 | 
            -
                    version: ' | 
| 44 | 
            -
                - - ">="
         | 
| 45 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 46 | 
            -
                    version: 1.0.2
         | 
| 40 | 
            +
                    version: '2.0'
         | 
| 47 41 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 42 | 
             
              name: oj
         | 
| 49 43 | 
             
              requirement: !ruby/object:Gem::Requirement
         |