tcp-client 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d0193d806cfa23c35c5378acd176d8a14d5e0d3b6c2dba9ba6d66a445f920228
4
- data.tar.gz: f7cc0fc3185e1ec25538eb778a878c3a209af9978ab7ad0787c0593a76a0bcf1
3
+ metadata.gz: b9cfd60cce36d13e734e17197f76d5d887eae87f9b4ec08ef00a43d6ea5d8d5a
4
+ data.tar.gz: ff17c9f4cb54ae7a6d00d888c34e45077b17c8225e26d1695854587ecb01f3dc
5
5
  SHA512:
6
- metadata.gz: f88bbc3c2d520345c515f46344324830456aa5f91f37c17c962cd4bf22373ea47521963761428f0a210bb3ca64a13cebafe1c439d4f6a494204a3187382c2528
7
- data.tar.gz: ac52537db4b04d7d2cfae9fcaf1444a23400c3b15bafec15b7f6cbc9eb707b332bc0bfd3e88ea219659aa8c3cc41e382065d9531f9e78e64b67cbddecb270554
6
+ metadata.gz: d2c03a28cc57eba3b3468ed911ac24bb7a24279bbe80d6ddea6fca8a65848b5079c409d968599348476e041e04ff891196a90014ce5cee19e5204fdfad78ed15
7
+ data.tar.gz: 68551bdbc6e978368cf615c2d68d078ceb20b8857fdd6451efba921efdf37bc25732e366d246126bb42006bffa50fa60540f30b3390f635080c99116b296f575
@@ -19,7 +19,7 @@ class TCPClient
19
19
  # @return [Addrinfo] the address info
20
20
  #
21
21
  def addrinfo
22
- freeze if @addrinfo.nil?
22
+ freeze unless @addrinfo
23
23
  @addrinfo
24
24
  end
25
25
 
@@ -28,7 +28,7 @@ class TCPClient
28
28
  # @return [String] the host name
29
29
  #
30
30
  def host
31
- freeze if @host.nil?
31
+ freeze unless @host
32
32
  @host
33
33
  end
34
34
  alias hostname host
@@ -37,9 +37,7 @@ class TCPClient
37
37
  # @attribute [r] port
38
38
  # @return [Integer] the port number
39
39
  #
40
- def port
41
- addrinfo.ip_port
42
- end
40
+ def port = addrinfo.ip_port
43
41
 
44
42
  #
45
43
  # Initializes an address
@@ -73,18 +71,14 @@ class TCPClient
73
71
  #
74
72
  # @param port [Integer] the addressed port
75
73
  #
76
- def initialize(addr)
77
- @addr = addr
78
- end
74
+ def initialize(addr) = (@addr = addr)
79
75
 
80
76
  #
81
77
  # Convert `self` to a Hash containing host and port attribute.
82
78
  #
83
79
  # @return [Hash] host and port
84
80
  #
85
- def to_hash
86
- { host: host, port: port }
87
- end
81
+ def to_hash = { host: host, port: port }
88
82
 
89
83
  #
90
84
  # Convert `self` to a Hash containing host and port attribute.
@@ -93,16 +87,12 @@ class TCPClient
93
87
  # @overload to_h(&block)
94
88
  # @return [Hash] host and port
95
89
  #
96
- def to_h(&block)
97
- block ? to_hash.to_h(&block) : to_hash
98
- end
90
+ def to_h(&block) = block ? to_hash.to_h(&block) : to_hash
99
91
 
100
92
  #
101
93
  # @return [String] text representation of self as "host:port"
102
94
  #
103
- def to_s
104
- host.index(':') ? "[#{host}]:#{port}" : "#{host}:#{port}"
105
- end
95
+ def to_s = host.index(':') ? "[#{host}]:#{port}" : "#{host}:#{port}"
106
96
 
107
97
  #
108
98
  # Force the address resolution and prevents further modifications of itself.
@@ -114,20 +104,15 @@ class TCPClient
114
104
  solve
115
105
  @addrinfo.freeze
116
106
  @host.freeze
117
- @addr = nil
118
107
  super
119
108
  end
120
109
 
121
110
  # @!visibility private
122
- def ==(other)
123
- to_hash == other.to_h
124
- end
111
+ def ==(other) = to_hash == other.to_h
125
112
  alias eql? ==
126
113
 
127
114
  # @!visibility private
128
- def equal?(other)
129
- self.class == other.class && self == other
130
- end
115
+ def equal?(other) = self.class == other.class && self == other
131
116
 
132
117
  private
133
118
 
@@ -142,6 +127,7 @@ class TCPClient
142
127
  else
143
128
  from_string(@addr)
144
129
  end
130
+ @addr = nil
145
131
  end
146
132
 
147
133
  def from_self_class(address)
@@ -154,14 +140,13 @@ class TCPClient
154
140
  end
155
141
 
156
142
  def from_addrinfo(addrinfo)
157
- @host = addrinfo.getnameinfo(Socket::NI_NUMERICSERV).first
158
- @addrinfo = addrinfo
143
+ @host = (@addrinfo = addrinfo).getnameinfo(Socket::NI_NUMERICSERV).first
159
144
  end
160
145
 
161
146
  def from_string(str)
162
147
  @host, port = host_n_port(str.to_s)
163
- return @addrinfo = Addrinfo.tcp(@host, port) if @host
164
- from_addrinfo(Addrinfo.tcp(nil, port))
148
+ @addrinfo = Addrinfo.tcp(@host, port)
149
+ @host ||= @addrinfo.getnameinfo(Socket::NI_NUMERICSERV).first
165
150
  end
166
151
 
167
152
  def host_n_port(str)
@@ -93,9 +93,7 @@ class TCPClient
93
93
  # @!parse attr_reader :ssl?
94
94
  # @return [Boolean] whether SSL is configured, see {#ssl_params}
95
95
  #
96
- def ssl?
97
- @ssl_params ? true : false
98
- end
96
+ def ssl? = @ssl_params ? true : false
99
97
 
100
98
  #
101
99
  # Parameters used to initialize a SSL context. SSL/TLS will only be used if
@@ -111,7 +109,7 @@ class TCPClient
111
109
  if value.respond_to?(:to_hash)
112
110
  Hash[value.to_hash]
113
111
  elsif value.respond_to?(:to_h)
114
- value.nil? ? nil : Hash[value.to_h]
112
+ value.nil? ? nil : value.to_h.dup
115
113
  else
116
114
  value ? {} : nil
117
115
  end
@@ -133,7 +131,7 @@ class TCPClient
133
131
  attr_reader :connect_timeout
134
132
 
135
133
  def connect_timeout=(value)
136
- @connect_timeout = seconds(value)
134
+ @connect_timeout = as_seconds(value)
137
135
  end
138
136
 
139
137
  #
@@ -146,8 +144,7 @@ class TCPClient
146
144
  attr_reader :connect_timeout_error
147
145
 
148
146
  def connect_timeout_error=(value)
149
- raise(NotAnExceptionError, value) unless exception_class?(value)
150
- @connect_timeout_error = value
147
+ @connect_timeout_error = as_exception(value)
151
148
  end
152
149
 
153
150
  #
@@ -161,7 +158,7 @@ class TCPClient
161
158
  attr_reader :read_timeout
162
159
 
163
160
  def read_timeout=(value)
164
- @read_timeout = seconds(value)
161
+ @read_timeout = as_seconds(value)
165
162
  end
166
163
 
167
164
  #
@@ -174,8 +171,7 @@ class TCPClient
174
171
  attr_reader :read_timeout_error
175
172
 
176
173
  def read_timeout_error=(value)
177
- raise(NotAnExceptionError, value) unless exception_class?(value)
178
- @read_timeout_error = value
174
+ @read_timeout_error = as_exception(value)
179
175
  end
180
176
 
181
177
  #
@@ -189,7 +185,7 @@ class TCPClient
189
185
  attr_reader :write_timeout
190
186
 
191
187
  def write_timeout=(value)
192
- @write_timeout = seconds(value)
188
+ @write_timeout = as_seconds(value)
193
189
  end
194
190
 
195
191
  #
@@ -202,8 +198,7 @@ class TCPClient
202
198
  attr_reader :write_timeout_error
203
199
 
204
200
  def write_timeout_error=(value)
205
- raise(NotAnExceptionError, value) unless exception_class?(value)
206
- @write_timeout_error = value
201
+ @write_timeout_error = as_exception(value)
207
202
  end
208
203
 
209
204
  #
@@ -218,7 +213,7 @@ class TCPClient
218
213
  # @see #write_timeout
219
214
  #
220
215
  def timeout=(value)
221
- @connect_timeout = @write_timeout = @read_timeout = seconds(value)
216
+ @connect_timeout = @write_timeout = @read_timeout = as_seconds(value)
222
217
  end
223
218
 
224
219
  #
@@ -235,9 +230,8 @@ class TCPClient
235
230
  # @see #write_timeout_error
236
231
  #
237
232
  def timeout_error=(value)
238
- raise(NotAnExceptionError, value) unless exception_class?(value)
239
233
  @connect_timeout_error =
240
- @read_timeout_error = @write_timeout_error = value
234
+ @read_timeout_error = @write_timeout_error = as_exception(value)
241
235
  end
242
236
 
243
237
  # @!endgroup
@@ -291,9 +285,7 @@ class TCPClient
291
285
  #
292
286
  # @see #configure
293
287
  #
294
- def to_h(&block)
295
- block ? to_hash.to_h(&block) : to_hash
296
- end
288
+ def to_h(&block) = block ? to_hash.to_h(&block) : to_hash
297
289
 
298
290
  #
299
291
  # Configures the instance with given options Hash.
@@ -318,7 +310,7 @@ class TCPClient
318
310
  # @return [Configuration] self
319
311
  #
320
312
  def configure(options)
321
- options.each_pair { |attribute, value| set(attribute, value) }
313
+ options.each_pair { set(*_1) }
322
314
  self
323
315
  end
324
316
 
@@ -336,30 +328,25 @@ class TCPClient
336
328
  end
337
329
 
338
330
  # @!visibility private
339
- def ==(other)
340
- to_hash == other.to_h
341
- end
331
+ def ==(other) = to_hash == other.to_h
342
332
  alias eql? ==
343
333
 
344
334
  # @!visibility private
345
- def equal?(other)
346
- self.class == other.class && self == other
347
- end
335
+ def equal?(other) = self.class == other.class && to_hash == other.to_hash
348
336
 
349
337
  private
350
338
 
351
- def exception_class?(value)
352
- value.is_a?(Class) && value < Exception
339
+ def as_seconds(value) = value&.to_f&.positive? ? value : nil
340
+
341
+ def as_exception(value)
342
+ return value if value.is_a?(Class) && value < Exception
343
+ raise(NotAnExceptionError, value, caller(2))
353
344
  end
354
345
 
355
346
  def set(attribute, value)
356
347
  public_send("#{attribute}=", value)
357
348
  rescue NoMethodError
358
- raise(UnknownAttributeError, attribute)
359
- end
360
-
361
- def seconds(value)
362
- value&.to_f&.positive? ? value : nil
349
+ raise(UnknownAttributeError, attribute, caller(2))
363
350
  end
364
351
  end
365
352
  end
@@ -7,9 +7,7 @@ class TCPClient
7
7
  @deadline = timeout&.positive? ? now + timeout : nil
8
8
  end
9
9
 
10
- def valid?
11
- !@deadline.nil?
12
- end
10
+ def valid? = !@deadline.nil?
13
11
 
14
12
  def remaining_time
15
13
  @deadline && (remaining = @deadline - now) > 0 ? remaining : nil
@@ -18,13 +16,9 @@ class TCPClient
18
16
  private
19
17
 
20
18
  if defined?(Process::CLOCK_MONOTONIC)
21
- def now
22
- Process.clock_gettime(Process::CLOCK_MONOTONIC)
23
- end
19
+ def now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
24
20
  else
25
- def now
26
- ::Time.now
27
- end
21
+ def now = ::Time.now
28
22
  end
29
23
  end
30
24
 
@@ -37,19 +37,15 @@ class TCPClient
37
37
  end
38
38
 
39
39
  class Configuration
40
- class << self
41
- #
42
- # @attribute [r] :default
43
- # @return [Configuration] used by default if no dedicated configuration
44
- # was specified
45
- #
46
- # @see TCPClient.open
47
- # @see TCPClient.with_deadline
48
- # @see TCPClient#connect
49
- #
50
- def default
51
- TCPClient.default_configuration
52
- end
53
- end
40
+ #
41
+ # @attribute [r] :default
42
+ # @return [Configuration] used by default if no dedicated configuration
43
+ # was specified
44
+ #
45
+ # @see TCPClient.open
46
+ # @see TCPClient.with_deadline
47
+ # @see TCPClient#connect
48
+ #
49
+ def self.default = TCPClient.default_configuration
54
50
  end
55
51
  end
@@ -6,9 +6,7 @@ class TCPClient
6
6
  # not available.
7
7
  #
8
8
  class NoOpenSSLError < RuntimeError
9
- def initialize
10
- super('OpenSSL is not available')
11
- end
9
+ def initialize = super('OpenSSL is not available')
12
10
  end
13
11
 
14
12
  #
@@ -16,9 +14,7 @@ class TCPClient
16
14
  # specified.
17
15
  #
18
16
  class NoBlockGivenError < ArgumentError
19
- def initialize
20
- super('no block given')
21
- end
17
+ def initialize = super('no block given')
22
18
  end
23
19
 
24
20
  #
@@ -28,9 +24,7 @@ class TCPClient
28
24
  #
29
25
  # @param timeout [Object] the invalid value
30
26
  #
31
- def initialize(timeout)
32
- super("invalid deadline - #{timeout}")
33
- end
27
+ def initialize(timeout) = super("invalid deadline - #{timeout}")
34
28
  end
35
29
 
36
30
  #
@@ -40,9 +34,7 @@ class TCPClient
40
34
  #
41
35
  # @param attribute [Object] the undefined attribute
42
36
  #
43
- def initialize(attribute)
44
- super("unknown attribute - #{attribute}")
45
- end
37
+ def initialize(attribute) = super("unknown attribute - #{attribute}")
46
38
  end
47
39
 
48
40
  #
@@ -74,9 +66,7 @@ class TCPClient
74
66
  # but is not connected.
75
67
  #
76
68
  class NotConnectedError < NetworkError
77
- def initialize
78
- super('client not connected')
79
- end
69
+ def initialize = super('client not connected')
80
70
  end
81
71
 
82
72
  #
@@ -104,9 +94,7 @@ class TCPClient
104
94
  # @attribute [r] action
105
95
  # @return [Symbol] the action which timed out
106
96
  #
107
- def action
108
- :process
109
- end
97
+ def action = :process
110
98
  end
111
99
 
112
100
  #
@@ -117,9 +105,7 @@ class TCPClient
117
105
  # @attribute [r] action
118
106
  # @return [Symbol] the action which timed out: `:connect`
119
107
  #
120
- def action
121
- :connect
122
- end
108
+ def action = :connect
123
109
  end
124
110
 
125
111
  #
@@ -130,9 +116,7 @@ class TCPClient
130
116
  # @attribute [r] action
131
117
  # @return [Symbol] the action which timed out: :read`
132
118
  #
133
- def action
134
- :read
135
- end
119
+ def action = :read
136
120
  end
137
121
 
138
122
  #
@@ -143,9 +127,7 @@ class TCPClient
143
127
  # @attribute [r] action
144
128
  # @return [Symbol] the action which timed out: `:write`
145
129
  #
146
- def action
147
- :write
148
- end
130
+ def action = :write
149
131
  end
150
132
 
151
133
  NoOpenSSL = NoOpenSSLError # @!visibility private
@@ -6,25 +6,18 @@ class TCPClient
6
6
  private
7
7
 
8
8
  def included(mod)
9
- return if supports_wait?(mod)
10
- mod.include(mod.method_defined?(:to_io) ? WaitWithIO : WaitWithSelect)
11
- end
12
-
13
- def supports_wait?(mod)
14
- mod.method_defined?(:wait_writable) &&
15
- mod.method_defined?(:wait_readable)
9
+ return if defined?(mod.wait_writable) && defined?(mod.wait_readable)
10
+ mod.include(defined?(mod.to_io) ? WaitWithIO : WaitWithSelect)
16
11
  end
17
12
  end
18
13
 
19
14
  def read_with_deadline(nbytes, deadline, exception)
20
15
  raise(exception) unless deadline.remaining_time
21
16
  return fetch_avail(deadline, exception) if nbytes.nil?
22
- return ''.b if nbytes.zero?
23
17
  @read_buffer ||= ''.b
24
18
  while @read_buffer.bytesize < nbytes
25
- read = fetch_next(deadline, exception) and next @read_buffer << read
26
- close
27
- break
19
+ read = fetch_next(deadline, exception)
20
+ read ? @read_buffer << read : (break close)
28
21
  end
29
22
  fetch_slice(nbytes)
30
23
  end
@@ -32,12 +25,10 @@ class TCPClient
32
25
  def read_to_with_deadline(sep, deadline, exception)
33
26
  raise(exception) unless deadline.remaining_time
34
27
  @read_buffer ||= ''.b
35
- while @read_buffer.index(sep).nil?
36
- read = fetch_next(deadline, exception) and next @read_buffer << read
37
- close
38
- break
28
+ while (index = @read_buffer.index(sep)).nil?
29
+ read = fetch_next(deadline, exception)
30
+ read ? @read_buffer << read : (break close)
39
31
  end
40
- index = @read_buffer.index(sep)
41
32
  return fetch_slice(index + sep.bytesize) if index
42
33
  result = @read_buffer
43
34
  @read_buffer = nil
@@ -53,7 +44,7 @@ class TCPClient
53
44
  with_deadline(deadline, exception) do
54
45
  write_nonblock(data, exception: false)
55
46
  end
56
- (result += written) >= size and return result
47
+ return result if (result += written) >= size
57
48
  data = data.byteslice(written, data.bytesize - written)
58
49
  end
59
50
  end
@@ -70,7 +61,7 @@ class TCPClient
70
61
  end
71
62
 
72
63
  def fetch_slice(size)
73
- return ''.b if size.zero?
64
+ return ''.b if size <= 0
74
65
  result = @read_buffer.byteslice(0, size)
75
66
  rest = @read_buffer.bytesize - result.bytesize
76
67
  @read_buffer = rest.zero? ? nil : @read_buffer.byteslice(size, rest)
@@ -101,23 +92,13 @@ class TCPClient
101
92
  end
102
93
 
103
94
  module WaitWithIO
104
- def wait_writable(remaining_time)
105
- to_io.wait_writable(remaining_time)
106
- end
107
-
108
- def wait_readable(remaining_time)
109
- to_io.wait_readable(remaining_time)
110
- end
95
+ def wait_writable(time) = to_io.wait_writable(time)
96
+ def wait_readable(time) = to_io.wait_readable(time)
111
97
  end
112
98
 
113
99
  module WaitWithSelect
114
- def wait_writable(remaining_time)
115
- ::IO.select(nil, [self], nil, remaining_time)
116
- end
117
-
118
- def wait_readable(remaining_time)
119
- ::IO.select([self], nil, nil, remaining_time)
120
- end
100
+ def wait_writable(time) = ::IO.select(nil, [self], nil, time)
101
+ def wait_readable(time) = ::IO.select([self], nil, nil, time)
121
102
  end
122
103
 
123
104
  private_constant(:WaitWithIO, :WaitWithSelect)
@@ -30,7 +30,7 @@ class TCPClient
30
30
  ::OpenSSL::SSL::SSLContext.new.tap do |ctx|
31
31
  ctx.set_params(ssl_params)
32
32
  ctx.session_cache_mode = CONTEXT_CACHE_MODE
33
- ctx.session_new_cb = proc { |_, session| @new_session = session }
33
+ ctx.session_new_cb = proc { @new_session = _2 }
34
34
  end
35
35
  end
36
36
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  class TCPClient
4
4
  # The current version number.
5
- VERSION = '0.13.0'
5
+ VERSION = '0.14.0'
6
6
  end
data/lib/tcp-client.rb CHANGED
@@ -92,7 +92,6 @@ class TCPClient
92
92
  # @see #with_deadline
93
93
  #
94
94
  def self.with_deadline(timeout, address, configuration = nil)
95
- client = nil
96
95
  raise(NoBlockGivenError) unless block_given?
97
96
  client = new
98
97
  client.with_deadline(timeout) do
@@ -116,9 +115,7 @@ class TCPClient
116
115
  # @attribute [r] :closed?
117
116
  # @return [Boolean] whether the connection is closed
118
117
  #
119
- def closed?
120
- @socket.nil? || @socket.closed?
121
- end
118
+ def closed? = @socket.nil? || @socket.closed?
122
119
 
123
120
  #
124
121
  # Close the current connection if connected.
@@ -240,9 +237,7 @@ class TCPClient
240
237
  #
241
238
  # @see Address#to_s
242
239
  #
243
- def to_s
244
- @address&.to_s || ''
245
- end
240
+ def to_s = @address.to_s
246
241
 
247
242
  #
248
243
  # Executes a block with a given overall time limit.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tcp-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-27 00:00:00.000000000 Z
11
+ date: 2024-03-09 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  This gem implements a customizable TCP client class that gives you control
@@ -59,7 +59,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  requirements: []
62
- rubygems_version: 3.4.22
62
+ rubygems_version: 3.5.6
63
63
  signing_key:
64
64
  specification_version: 4
65
65
  summary: Use your TCP connections with working timeout.