tcp-client 0.13.0 → 0.14.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 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.