jrpc 1.1.8 → 2.1.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/.github/workflows/ci.yml +55 -0
- data/.rspec +1 -0
- data/.rubocop.yml +228 -0
- data/CHANGELOG.md +67 -0
- data/Gemfile +17 -0
- data/README.md +240 -13
- data/Rakefile +3 -1
- data/bin/console +1 -0
- data/bin/jrpc +37 -26
- data/bin/jrpc-shell +34 -24
- data/jrpc.gemspec +6 -8
- data/lib/jrpc/errors.rb +65 -0
- data/lib/jrpc/id_generator.rb +22 -0
- data/lib/jrpc/message.rb +78 -0
- data/lib/jrpc/payload_logging.rb +19 -0
- data/lib/jrpc/shared_client/outbound_queue.rb +71 -0
- data/lib/jrpc/shared_client/registry.rb +46 -0
- data/lib/jrpc/shared_client/ticket.rb +84 -0
- data/lib/jrpc/shared_client/transport_loop.rb +298 -0
- data/lib/jrpc/shared_client.rb +194 -0
- data/lib/jrpc/simple_client.rb +98 -0
- data/lib/jrpc/transport/base.rb +63 -0
- data/lib/jrpc/transport/tcp.rb +292 -0
- data/lib/jrpc/transport/test.rb +333 -0
- data/lib/jrpc/transport.rb +12 -0
- data/lib/jrpc/version.rb +3 -1
- data/lib/jrpc.rb +14 -16
- metadata +25 -71
- data/.travis.yml +0 -4
- data/lib/jrpc/base_client.rb +0 -123
- data/lib/jrpc/error/client_error.rb +0 -5
- data/lib/jrpc/error/connection_error.rb +0 -11
- data/lib/jrpc/error/error.rb +0 -5
- data/lib/jrpc/error/internal_error.rb +0 -9
- data/lib/jrpc/error/internal_server_error.rb +0 -5
- data/lib/jrpc/error/invalid_params.rb +0 -9
- data/lib/jrpc/error/invalid_request.rb +0 -9
- data/lib/jrpc/error/method_not_found.rb +0 -9
- data/lib/jrpc/error/parse_error.rb +0 -9
- data/lib/jrpc/error/server_error.rb +0 -11
- data/lib/jrpc/error/unknown_error.rb +0 -5
- data/lib/jrpc/tcp_client.rb +0 -112
- data/lib/jrpc/transport/socket_base.rb +0 -88
- data/lib/jrpc/transport/socket_tcp.rb +0 -132
- data/lib/jrpc/utils.rb +0 -9
metadata
CHANGED
|
@@ -1,85 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jrpc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Denis Talakevich
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: concurrent-ruby
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: oj
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - "~>"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '3.0'
|
|
18
|
+
version: '1.2'
|
|
34
19
|
type: :runtime
|
|
35
20
|
prerelease: false
|
|
36
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
22
|
requirements:
|
|
38
23
|
- - "~>"
|
|
39
24
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
25
|
+
version: '1.2'
|
|
41
26
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
27
|
+
name: logger
|
|
43
28
|
requirement: !ruby/object:Gem::Requirement
|
|
44
29
|
requirements:
|
|
45
30
|
- - ">="
|
|
46
31
|
- !ruby/object:Gem::Version
|
|
47
32
|
version: '0'
|
|
48
|
-
type: :
|
|
33
|
+
type: :runtime
|
|
49
34
|
prerelease: false
|
|
50
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
36
|
requirements:
|
|
52
37
|
- - ">="
|
|
53
38
|
- !ruby/object:Gem::Version
|
|
54
39
|
version: '0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: rake
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '13.0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '13.0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: rspec
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - "~>"
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '3.0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - "~>"
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '3.0'
|
|
83
40
|
description: JSON RPC client over TCP
|
|
84
41
|
email:
|
|
85
42
|
- senid231@gmail.com
|
|
@@ -89,9 +46,10 @@ executables:
|
|
|
89
46
|
extensions: []
|
|
90
47
|
extra_rdoc_files: []
|
|
91
48
|
files:
|
|
49
|
+
- ".github/workflows/ci.yml"
|
|
92
50
|
- ".gitignore"
|
|
93
51
|
- ".rspec"
|
|
94
|
-
- ".
|
|
52
|
+
- ".rubocop.yml"
|
|
95
53
|
- CHANGELOG.md
|
|
96
54
|
- Gemfile
|
|
97
55
|
- LICENSE.txt
|
|
@@ -103,28 +61,25 @@ files:
|
|
|
103
61
|
- bin/setup
|
|
104
62
|
- jrpc.gemspec
|
|
105
63
|
- lib/jrpc.rb
|
|
106
|
-
- lib/jrpc/
|
|
107
|
-
- lib/jrpc/
|
|
108
|
-
- lib/jrpc/
|
|
109
|
-
- lib/jrpc/
|
|
110
|
-
- lib/jrpc/
|
|
111
|
-
- lib/jrpc/
|
|
112
|
-
- lib/jrpc/
|
|
113
|
-
- lib/jrpc/
|
|
114
|
-
- lib/jrpc/
|
|
115
|
-
- lib/jrpc/
|
|
116
|
-
- lib/jrpc/
|
|
117
|
-
- lib/jrpc/
|
|
118
|
-
- lib/jrpc/
|
|
119
|
-
- lib/jrpc/transport/
|
|
120
|
-
- lib/jrpc/transport/socket_tcp.rb
|
|
121
|
-
- lib/jrpc/utils.rb
|
|
64
|
+
- lib/jrpc/errors.rb
|
|
65
|
+
- lib/jrpc/id_generator.rb
|
|
66
|
+
- lib/jrpc/message.rb
|
|
67
|
+
- lib/jrpc/payload_logging.rb
|
|
68
|
+
- lib/jrpc/shared_client.rb
|
|
69
|
+
- lib/jrpc/shared_client/outbound_queue.rb
|
|
70
|
+
- lib/jrpc/shared_client/registry.rb
|
|
71
|
+
- lib/jrpc/shared_client/ticket.rb
|
|
72
|
+
- lib/jrpc/shared_client/transport_loop.rb
|
|
73
|
+
- lib/jrpc/simple_client.rb
|
|
74
|
+
- lib/jrpc/transport.rb
|
|
75
|
+
- lib/jrpc/transport/base.rb
|
|
76
|
+
- lib/jrpc/transport/tcp.rb
|
|
77
|
+
- lib/jrpc/transport/test.rb
|
|
122
78
|
- lib/jrpc/version.rb
|
|
123
79
|
homepage: https://github.com/didww/jrpc
|
|
124
80
|
licenses:
|
|
125
81
|
- MIT
|
|
126
82
|
metadata: {}
|
|
127
|
-
post_install_message:
|
|
128
83
|
rdoc_options: []
|
|
129
84
|
require_paths:
|
|
130
85
|
- lib
|
|
@@ -132,15 +87,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
132
87
|
requirements:
|
|
133
88
|
- - ">="
|
|
134
89
|
- !ruby/object:Gem::Version
|
|
135
|
-
version: '
|
|
90
|
+
version: '3.3'
|
|
136
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
92
|
requirements:
|
|
138
93
|
- - ">="
|
|
139
94
|
- !ruby/object:Gem::Version
|
|
140
95
|
version: '0'
|
|
141
96
|
requirements: []
|
|
142
|
-
rubygems_version: 3.
|
|
143
|
-
signing_key:
|
|
97
|
+
rubygems_version: 3.6.9
|
|
144
98
|
specification_version: 4
|
|
145
99
|
summary: JSON RPC client
|
|
146
100
|
test_files: []
|
data/.travis.yml
DELETED
data/lib/jrpc/base_client.rb
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
require 'oj'
|
|
2
|
-
require 'forwardable'
|
|
3
|
-
module JRPC
|
|
4
|
-
class BaseClient
|
|
5
|
-
extend Forwardable
|
|
6
|
-
|
|
7
|
-
attr_reader :uri, :options
|
|
8
|
-
|
|
9
|
-
ID_CHARACTERS = (('a'..'z').to_a + ('0'..'9').to_a + ('A'..'Z').to_a).freeze
|
|
10
|
-
REQUEST_TYPES = [:request, :notification].freeze
|
|
11
|
-
|
|
12
|
-
def self.connect(uri, options)
|
|
13
|
-
client = new(uri, options)
|
|
14
|
-
yield(client)
|
|
15
|
-
ensure
|
|
16
|
-
client.close if client
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def initialize(uri, options)
|
|
20
|
-
@uri = uri
|
|
21
|
-
@options = options
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def method_missing(method, *params)
|
|
25
|
-
invoke_request(method, *params)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def perform_request(method, params: nil, type: :request, read_timeout: nil, write_timeout: nil)
|
|
29
|
-
validate_request(params, type)
|
|
30
|
-
request = create_message(method.to_s, params)
|
|
31
|
-
if type == :request
|
|
32
|
-
id = generate_id
|
|
33
|
-
request['id'] = id
|
|
34
|
-
response = send_command serialize_request(request), read_timeout: read_timeout, write_timeout: write_timeout
|
|
35
|
-
response = deserialize_response(response)
|
|
36
|
-
|
|
37
|
-
validate_response(response, id)
|
|
38
|
-
parse_error(response['error']) if response.has_key?('error')
|
|
39
|
-
|
|
40
|
-
response['result']
|
|
41
|
-
else
|
|
42
|
-
send_notification serialize_request(request), write_timeout: write_timeout
|
|
43
|
-
nil
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def invoke_request(method, *params)
|
|
48
|
-
warn '[DEPRECATION] `invoke_request` is deprecated. Please use `perform_request` instead.'
|
|
49
|
-
params = nil if params.empty?
|
|
50
|
-
perform_request(method, params: params)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def invoke_notification(method, *params)
|
|
54
|
-
warn '[DEPRECATION] `invoke_request` is deprecated. Please use `perform_request` instead.'
|
|
55
|
-
params = nil if params.empty?
|
|
56
|
-
perform_request(method, params: params, type: :notification)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
private
|
|
60
|
-
|
|
61
|
-
def serialize_request(request)
|
|
62
|
-
Oj.dump(request, mode: :compat)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def deserialize_response(response)
|
|
66
|
-
Oj.load(response)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def validate_response(response, id)
|
|
70
|
-
raise ClientError, 'Wrong response structure' unless response.is_a?(Hash)
|
|
71
|
-
raise ClientError, 'Wrong version' if response['jsonrpc'] != JRPC::JSON_RPC_VERSION
|
|
72
|
-
if id != response['id']
|
|
73
|
-
raise ClientError, "ID response mismatch. expected #{id.inspect} got #{response['id'].inspect}"
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def validate_request(params, type)
|
|
78
|
-
raise ClientError, 'invalid type' unless REQUEST_TYPES.include?(type)
|
|
79
|
-
raise ClientError, 'invalid params' if !params.nil? && !params.is_a?(Array) && !params.is_a?(Hash)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def parse_error(error)
|
|
83
|
-
case error['code']
|
|
84
|
-
when -32700
|
|
85
|
-
raise ParseError.new(error['message'])
|
|
86
|
-
when -32600
|
|
87
|
-
raise InvalidRequest.new(error['message'])
|
|
88
|
-
when -32601
|
|
89
|
-
raise MethodNotFound.new(error['message'])
|
|
90
|
-
when -32602
|
|
91
|
-
raise InvalidParams.new(error['message'])
|
|
92
|
-
when -32603
|
|
93
|
-
raise InternalError.new(error['message'])
|
|
94
|
-
when -32099..-32000
|
|
95
|
-
raise InternalServerError.new(error['message'], error['code'])
|
|
96
|
-
else
|
|
97
|
-
raise UnknownError.new(error['message'], error['code'])
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def send_command(json, options={})
|
|
102
|
-
raise NotImplementedError
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def send_notification(json, options={})
|
|
106
|
-
raise NotImplementedError
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def generate_id
|
|
110
|
-
size = ID_CHARACTERS.size
|
|
111
|
-
(0...32).map { ID_CHARACTERS.to_a[rand(size)] }.join
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def create_message(method, params)
|
|
115
|
-
message = {
|
|
116
|
-
'jsonrpc' => JSON_RPC_VERSION,
|
|
117
|
-
'method' => method
|
|
118
|
-
}
|
|
119
|
-
message['params'] = params unless params.nil?
|
|
120
|
-
message
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
data/lib/jrpc/error/error.rb
DELETED
data/lib/jrpc/tcp_client.rb
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
require 'netstring'
|
|
2
|
-
require 'logger'
|
|
3
|
-
require 'benchmark'
|
|
4
|
-
module JRPC
|
|
5
|
-
class TcpClient < BaseClient
|
|
6
|
-
attr_reader :namespace, :transport
|
|
7
|
-
attr_accessor :logger
|
|
8
|
-
def_delegators :@transport, :close, :closed?, :connect
|
|
9
|
-
|
|
10
|
-
MAX_LOGGED_MESSAGE_LENGTH = 255
|
|
11
|
-
|
|
12
|
-
def initialize(uri, options = {})
|
|
13
|
-
super
|
|
14
|
-
@logger = @options.delete(:logger) || Logger.new($null)
|
|
15
|
-
@namespace = @options.delete(:namespace).to_s
|
|
16
|
-
|
|
17
|
-
timeout = @options.fetch(:timeout, 5)
|
|
18
|
-
connect_timeout = @options.fetch(:connect_timeout, timeout)
|
|
19
|
-
read_timeout = @options.fetch(:read_timeout, timeout)
|
|
20
|
-
write_timeout = @options.fetch(:write_timeout, 60) # default 60
|
|
21
|
-
connect_retry_count = @options.fetch(:connect_retry_count, 10) # default 10
|
|
22
|
-
@close_after_sent = @options.fetch(:close_after_sent, false)
|
|
23
|
-
|
|
24
|
-
@transport = JRPC::Transport::SocketTcp.new server: @uri,
|
|
25
|
-
connect_retry_count: connect_retry_count,
|
|
26
|
-
connect_timeout: connect_timeout,
|
|
27
|
-
read_timeout: read_timeout,
|
|
28
|
-
write_timeout: write_timeout
|
|
29
|
-
begin
|
|
30
|
-
@transport.connect
|
|
31
|
-
rescue JRPC::Transport::SocketTcp::Error
|
|
32
|
-
raise ConnectionError, "Can't connect to #{@uri}"
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
def ensure_connected
|
|
39
|
-
if @transport.closed?
|
|
40
|
-
logger.debug { 'Connecting transport...' }
|
|
41
|
-
@transport.connect
|
|
42
|
-
logger.debug { 'Connected.' }
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def send_command(request, options = {})
|
|
47
|
-
ensure_connected
|
|
48
|
-
read_timeout = options.fetch(:read_timeout)
|
|
49
|
-
write_timeout = options.fetch(:write_timeout)
|
|
50
|
-
response = nil
|
|
51
|
-
t = Benchmark.realtime do
|
|
52
|
-
logger.debug { "Request address: #{uri}" }
|
|
53
|
-
logger.debug { "Request message: #{Utils.truncate(request, MAX_LOGGED_MESSAGE_LENGTH)}" }
|
|
54
|
-
logger.debug { "Request read_timeout: #{read_timeout}" }
|
|
55
|
-
logger.debug { "Request write_timeout: #{write_timeout}" }
|
|
56
|
-
send_request(request, write_timeout)
|
|
57
|
-
response = receive_response(read_timeout)
|
|
58
|
-
end
|
|
59
|
-
logger.debug do
|
|
60
|
-
"(#{'%.2f' % (t * 1000)}ms) Response message: #{Utils.truncate(response, MAX_LOGGED_MESSAGE_LENGTH)}"
|
|
61
|
-
end
|
|
62
|
-
response
|
|
63
|
-
ensure
|
|
64
|
-
@transport.close if @close_after_sent
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def send_notification(request, options = {})
|
|
68
|
-
ensure_connected
|
|
69
|
-
write_timeout = options.fetch(:write_timeout)
|
|
70
|
-
logger.debug { "Request address: #{uri}" }
|
|
71
|
-
logger.debug { "Request message: #{Utils.truncate(request, MAX_LOGGED_MESSAGE_LENGTH)}" }
|
|
72
|
-
logger.debug { "Request write_timeout: #{write_timeout}" }
|
|
73
|
-
send_request(request, write_timeout)
|
|
74
|
-
logger.debug { 'No response required' }
|
|
75
|
-
ensure
|
|
76
|
-
@transport.close if @close_after_sent
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def create_message(method, params)
|
|
80
|
-
super("#{namespace}#{method}", params)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def send_request(request, timeout)
|
|
84
|
-
timeout ||= @transport.write_timeout
|
|
85
|
-
@transport.write Netstring.dump(request.to_s), timeout
|
|
86
|
-
rescue ::SocketError
|
|
87
|
-
raise ConnectionError, "Can't send request to #{uri}"
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def receive_response(timeout)
|
|
91
|
-
timeout ||= @transport.read_timeout
|
|
92
|
-
length = get_msg_length(timeout)
|
|
93
|
-
response = @transport.read(length + 1, timeout)
|
|
94
|
-
raise ClientError.new('invalid response. missed comma as terminator') if response[-1] != ','
|
|
95
|
-
response.chomp(',')
|
|
96
|
-
rescue ::SocketError
|
|
97
|
-
raise ConnectionError, "Can't receive response from #{uri}"
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def get_msg_length(timeout)
|
|
101
|
-
length = ''
|
|
102
|
-
while true do
|
|
103
|
-
character = @transport.read(1, timeout)
|
|
104
|
-
break if character == ':'
|
|
105
|
-
length += character
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
Integer(length)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
end
|
|
112
|
-
end
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
module JRPC
|
|
2
|
-
module Transport
|
|
3
|
-
class SocketBase
|
|
4
|
-
|
|
5
|
-
class Error < ::JRPC::Error
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
class TimeoutError < Error
|
|
9
|
-
def initialize
|
|
10
|
-
super(self.class.to_s.split('::').last)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class ReadTimeoutError < TimeoutError
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
class WriteTimeoutError < TimeoutError
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
class ConnectionTimeoutError < TimeoutError
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
class ConnectionFailedError < Error
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
class WriteFailedError < Error
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
class ReadFailedError < Error
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
attr_reader :options, :read_timeout, :write_timeout
|
|
33
|
-
|
|
34
|
-
def self.connect(options)
|
|
35
|
-
connection = new(options)
|
|
36
|
-
yield(connection)
|
|
37
|
-
ensure
|
|
38
|
-
connection.close if connection
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def initialize(options)
|
|
42
|
-
@server = options.fetch(:server)
|
|
43
|
-
@read_timeout = options.fetch(:read_timeout, nil)
|
|
44
|
-
@write_timeout = options.fetch(:write_timeout, nil)
|
|
45
|
-
@connect_timeout = options.fetch(:connect_timeout, nil)
|
|
46
|
-
@connect_retry_count = options.fetch(:connect_retry_count, 0)
|
|
47
|
-
@options = options
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def connect
|
|
51
|
-
retries = @connect_retry_count
|
|
52
|
-
|
|
53
|
-
while retries >= 0
|
|
54
|
-
begin
|
|
55
|
-
connect_socket
|
|
56
|
-
break
|
|
57
|
-
rescue Error => e
|
|
58
|
-
retries -= 1
|
|
59
|
-
raise e if retries < 0
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def read(_length, _timeout = @read_timeout)
|
|
65
|
-
raise NotImplementedError
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def write(_data, _timeout = @write_timeout)
|
|
69
|
-
raise NotImplementedError
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def close
|
|
73
|
-
raise NotImplementedError
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def closed?
|
|
77
|
-
raise NotImplementedError
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
private
|
|
81
|
-
|
|
82
|
-
def connect_socket
|
|
83
|
-
raise NotImplementedError
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|