tcp-client 0.2.3 → 0.3.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: 2791642003fb16623a27988401ff3bb532194032a5bbd4f62b853aae94790055
4
- data.tar.gz: 030a2b3ebecf1334dea84e2c8f18aecd3b900c7c467c10c624c1354429a66195
3
+ metadata.gz: a9ec3cdc6d442ed7e748f9993d32be41d3dbe20b06bbced35ba0f5ba96caf47f
4
+ data.tar.gz: ef601054036a671f2073e6b8bbe02e0c23c182a5646db715e27a96a8b32a2485
5
5
  SHA512:
6
- metadata.gz: e4ef14d49cd323a418190e62bc190af01fcc9be1b7008b7fd27c8fa7b8779ae29947045a660080e9403ba1d932e1318a6f98c819006d816f91eb093caf6d7873
7
- data.tar.gz: 29617e860ad0b419638b54a8258541ccf3c668530a38aa2e629badcb373b94df71c33e538d54faf12d732ffd51670e1ad57cc8fabcaac11bb2d4de3d28cd29b1
6
+ metadata.gz: bd9f757eb175ecf86be1973126991e8a6b4cf50013c4d54854d9accff007e235003f5506b509729e8158ca1c43c05405ecc15802e207a719f44f45d22a4973d7
7
+ data.tar.gz: d30bd7e5361f310b49bf20357e814a495d0a3b7962f0a6a59e108cb978f0ca1785cc8ba5a4c349d90e0c191cd50dfb7a26b2084f7f36cb590f48237c592ea77c
data/lib/tcp-client.rb CHANGED
@@ -29,7 +29,7 @@ class TCPClient
29
29
 
30
30
  def connect(addr, configuration, exception: nil)
31
31
  close
32
- NoOpenSSL.raise! if configuration.ssl? && !defined?(SSLSocket)
32
+ raise(NoOpenSSL) if configuration.ssl? && !defined?(SSLSocket)
33
33
  @address = Address.new(addr)
34
34
  @cfg = configuration.dup
35
35
  exception ||= configuration.connect_timeout_error
@@ -54,9 +54,9 @@ class TCPClient
54
54
 
55
55
  def with_deadline(timeout)
56
56
  previous_deadline = @deadline
57
- NoBlockGiven.raise! unless block_given?
57
+ raise(NoBlockGiven) unless block_given?
58
58
  tm = timeout&.to_f
59
- InvalidDeadLine.raise! unless tm&.positive?
59
+ raise(InvalidDeadLine) unless tm&.positive?
60
60
  @deadline = Time.now + tm
61
61
  yield(self)
62
62
  ensure
@@ -64,7 +64,7 @@ class TCPClient
64
64
  end
65
65
 
66
66
  def read(nbytes, timeout: nil, exception: nil)
67
- NotConnected.raise! if closed?
67
+ raise(NotConnected) if closed?
68
68
  timeout.nil? && @deadline and
69
69
  return read_with_deadline(nbytes, @deadline, exception)
70
70
  timeout = (timeout || @cfg.read_timeout).to_f
@@ -73,7 +73,7 @@ class TCPClient
73
73
  end
74
74
 
75
75
  def write(*msg, timeout: nil, exception: nil)
76
- NotConnected.raise! if closed?
76
+ raise(NotConnected) if closed?
77
77
  timeout.nil? && @deadline and
78
78
  return write_with_deadline(msg, @deadline, exception)
79
79
  timeout = (timeout || @cfg.write_timeout).to_f
@@ -98,10 +98,8 @@ class TCPClient
98
98
 
99
99
  def write_with_deadline(msg, deadline, exception)
100
100
  exception ||= @cfg.write_timeout_error
101
- result = 0
102
- msg.each do |chunk|
103
- result += @socket.write_with_deadline(chunk.b, deadline, exception)
101
+ msg.sum do |chunk|
102
+ @socket.write_with_deadline(chunk.b, deadline, exception)
104
103
  end
105
- result
106
104
  end
107
105
  end
@@ -10,10 +10,10 @@ class TCPClient
10
10
  case addr
11
11
  when self.class
12
12
  init_from_selfclass(addr)
13
- when Integer
14
- init_from_addrinfo(Addrinfo.tcp(nil, addr))
15
13
  when Addrinfo
16
14
  init_from_addrinfo(addr)
15
+ when Integer
16
+ init_from_addrinfo(Addrinfo.tcp(nil, addr))
17
17
  else
18
18
  init_from_string(addr)
19
19
  end
@@ -59,7 +59,9 @@ class TCPClient
59
59
  def from_string(str)
60
60
  idx = str.rindex(':') or return nil, str.to_i
61
61
  name = str[0, idx]
62
- name = name[1, name.size - 2] if name[0] == '[' && name[-1] == ']'
62
+ if name.start_with?('[') && name.end_with?(']')
63
+ name = name[1, name.size - 2]
64
+ end
63
65
  [name, str[idx + 1, str.size - idx].to_i]
64
66
  end
65
67
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'errors'
2
4
 
3
5
  class TCPClient
@@ -80,23 +82,23 @@ class TCPClient
80
82
  end
81
83
 
82
84
  def timeout_error=(exception)
83
- NotAnException.raise!(exception) unless exception_class?(exception)
85
+ raise(NotAnException, exception) unless exception_class?(exception)
84
86
  @connect_timeout_error =
85
87
  @read_timeout_error = @write_timeout_error = exception
86
88
  end
87
89
 
88
90
  def connect_timeout_error=(exception)
89
- NotAnException.raise!(exception) unless exception_class?(exception)
91
+ raise(NotAnException, exception) unless exception_class?(exception)
90
92
  @connect_timeout_error = exception
91
93
  end
92
94
 
93
95
  def read_timeout_error=(exception)
94
- NotAnException.raise!(exception) unless exception_class?(exception)
96
+ raise(NotAnException, exception) unless exception_class?(exception)
95
97
  @read_timeout_error = exception
96
98
  end
97
99
 
98
100
  def write_timeout_error=(exception)
99
- NotAnException.raise!(exception) unless exception_class?(exception)
101
+ raise(NotAnException, exception) unless exception_class?(exception)
100
102
  @write_timeout_error = exception
101
103
  end
102
104
 
@@ -134,7 +136,7 @@ class TCPClient
134
136
  def set(attribute, value)
135
137
  public_send("#{attribute}=", value)
136
138
  rescue NoMethodError
137
- UnknownAttribute.raise!(attribute)
139
+ raise(UnknownAttribute, attribute)
138
140
  end
139
141
 
140
142
  def seconds(value)
@@ -4,45 +4,68 @@ require 'socket'
4
4
 
5
5
  class TCPClient
6
6
  class NoOpenSSL < RuntimeError
7
- def self.raise!
8
- raise(self, 'OpenSSL is not avail', caller(1))
7
+ def initialize
8
+ super('OpenSSL is not avail')
9
9
  end
10
10
  end
11
11
 
12
- class NoBlockGiven < RuntimeError
13
- def self.raise!
14
- raise(self, 'no block given', caller(1))
12
+ class NoBlockGiven < ArgumentError
13
+ def initialize
14
+ super('no block given')
15
15
  end
16
16
  end
17
17
 
18
18
  class InvalidDeadLine < ArgumentError
19
- def self.raise!(timeout)
20
- raise(self, "invalid deadline - #{timeout}", caller(1))
19
+ def initialize(timeout)
20
+ super("invalid deadline - #{timeout}")
21
21
  end
22
22
  end
23
23
 
24
24
  class UnknownAttribute < ArgumentError
25
- def self.raise!(attribute)
26
- raise(self, "unknown attribute - #{attribute}", caller(1))
25
+ def initialize(attribute)
26
+ super("unknown attribute - #{attribute}")
27
27
  end
28
28
  end
29
29
 
30
30
  class NotAnException < TypeError
31
- def self.raise!(object)
32
- raise(self, "not a valid exception class - #{object.inspect}", caller(1))
31
+ def initialize(object)
32
+ super("not a valid exception class - #{object.inspect}")
33
33
  end
34
34
  end
35
35
 
36
- class NotConnected < SocketError
37
- def self.raise!
38
- raise(self, 'client not connected', caller(1))
36
+ class NotConnected < IOError
37
+ def initialize
38
+ super('client not connected')
39
39
  end
40
40
  end
41
41
 
42
- TimeoutError = Class.new(IOError)
43
- ConnectTimeoutError = Class.new(TimeoutError)
44
- ReadTimeoutError = Class.new(TimeoutError)
45
- WriteTimeoutError = Class.new(TimeoutError)
42
+ class TimeoutError < IOError
43
+ def initialize(message = nil)
44
+ super(message || "unable to #{action} in time")
45
+ end
46
+
47
+ def action
48
+ :process
49
+ end
50
+ end
51
+
52
+ class ConnectTimeoutError < TimeoutError
53
+ def action
54
+ :connect
55
+ end
56
+ end
57
+
58
+ class ReadTimeoutError < TimeoutError
59
+ def action
60
+ :read
61
+ end
62
+ end
63
+
64
+ class WriteTimeoutError < TimeoutError
65
+ def action
66
+ :write
67
+ end
68
+ end
46
69
 
47
70
  Timeout = TimeoutError # backward compatibility
48
71
  deprecate_constant(:Timeout)
@@ -1,38 +1,38 @@
1
1
  module IOWithDeadlineMixin
2
2
  def self.included(mod)
3
- im = mod.instance_methods
4
- if im.index(:wait_writable) && im.index(:wait_readable)
3
+ methods = mod.instance_methods
4
+ if methods.index(:wait_writable) && methods.index(:wait_readable)
5
5
  mod.include(ViaWaitMethod)
6
6
  else
7
7
  mod.include(ViaSelect)
8
8
  end
9
9
  end
10
10
 
11
- def read_with_deadline(nbytes, deadline, exclass)
12
- raise(exclass) if Time.now > deadline
11
+ def read_with_deadline(bytes_to_read, deadline, exception)
12
+ raise(exception) if Time.now > deadline
13
13
  result = ''.b
14
- return result if nbytes.zero?
14
+ return result if bytes_to_read <= 0
15
15
  loop do
16
16
  read =
17
- with_deadline(deadline, exclass) do
18
- read_nonblock(nbytes - result.bytesize, exception: false)
17
+ with_deadline(deadline, exception) do
18
+ read_nonblock(bytes_to_read - result.bytesize, exception: false)
19
19
  end
20
20
  unless read
21
21
  close
22
22
  return result
23
23
  end
24
24
  result += read
25
- return result if result.bytesize >= nbytes
25
+ return result if result.bytesize >= bytes_to_read
26
26
  end
27
27
  end
28
28
 
29
- def write_with_deadline(data, deadline, exclass)
30
- raise(exclass) if Time.now > deadline
29
+ def write_with_deadline(data, deadline, exception)
30
+ raise(exception) if Time.now > deadline
31
31
  return 0 if (size = data.bytesize).zero?
32
32
  result = 0
33
33
  loop do
34
34
  written =
35
- with_deadline(deadline, exclass) do
35
+ with_deadline(deadline, exception) do
36
36
  write_nonblock(data, exception: false)
37
37
  end
38
38
  result += written
@@ -42,40 +42,40 @@ module IOWithDeadlineMixin
42
42
  end
43
43
 
44
44
  module ViaWaitMethod
45
- private def with_deadline(deadline, exclass)
45
+ private def with_deadline(deadline, exception)
46
46
  loop do
47
47
  case ret = yield
48
48
  when :wait_writable
49
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
50
- raise(exclass) if wait_writable(remaining_time).nil?
49
+ raise(exception) if (remaining_time = deadline - Time.now) <= 0
50
+ raise(exception) if wait_writable(remaining_time).nil?
51
51
  when :wait_readable
52
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
53
- raise(exclass) if wait_readable(remaining_time).nil?
52
+ raise(exception) if (remaining_time = deadline - Time.now) <= 0
53
+ raise(exception) if wait_readable(remaining_time).nil?
54
54
  else
55
55
  return ret
56
56
  end
57
57
  end
58
58
  rescue Errno::ETIMEDOUT
59
- raise(exclass)
59
+ raise(exception)
60
60
  end
61
61
  end
62
62
 
63
63
  module ViaSelect
64
- private def with_deadline(deadline, exclass)
64
+ private def with_deadline(deadline, exception)
65
65
  loop do
66
66
  case ret = yield
67
67
  when :wait_writable
68
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
69
- raise(exclass) if ::IO.select(nil, [self], nil, remaining_time).nil?
68
+ raise(exception) if (remaining_time = deadline - Time.now) <= 0
69
+ raise(exception) if ::IO.select(nil, [self], nil, remaining_time).nil?
70
70
  when :wait_readable
71
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
72
- raise(exclass) if ::IO.select([self], nil, nil, remaining_time).nil?
71
+ raise(exception) if (remaining_time = deadline - Time.now) <= 0
72
+ raise(exception) if ::IO.select([self], nil, nil, remaining_time).nil?
73
73
  else
74
74
  return ret
75
75
  end
76
76
  end
77
77
  rescue Errno::ETIMEDOUT
78
- raise(exclass)
78
+ raise(exception)
79
79
  end
80
80
  end
81
81
 
@@ -24,9 +24,9 @@ class TCPClient
24
24
  private
25
25
 
26
26
  def create_context(ssl_params)
27
- ctx = OpenSSL::SSL::SSLContext.new
28
- ctx.set_params(ssl_params)
29
- ctx
27
+ context = OpenSSL::SSL::SSLContext.new
28
+ context.set_params(ssl_params)
29
+ context
30
30
  end
31
31
 
32
32
  def connect_to(address, check, timeout, exception)
@@ -1,3 +1,3 @@
1
1
  class TCPClient
2
- VERSION = '0.2.3'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
@@ -118,7 +118,7 @@ class TCPClientTest < MiniTest::Test
118
118
  end
119
119
  end
120
120
 
121
- def xtest_read_write_deadline
121
+ def test_read_write_deadline
122
122
  TCPClient.open('localhost:1234', config) do |subject|
123
123
  refute(subject.closed?)
124
124
  assert_raises(TCPClient::TimeoutError) do
@@ -139,7 +139,7 @@ class TCPClientTest < MiniTest::Test
139
139
  start_time = Time.now
140
140
  TCPClient.new.connect('localhost:1234', ssl_config)
141
141
  end
142
- assert_in_delta(ssl_config.connect_timeout, Time.now - start_time, 0.11)
142
+ assert_in_delta(ssl_config.connect_timeout, Time.now - start_time, 0.25)
143
143
  end
144
144
 
145
145
  def test_connect_ssl_timeout
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.2.3
4
+ version: 0.3.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: 2021-05-19 00:00:00.000000000 Z
11
+ date: 2021-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -72,7 +72,6 @@ files:
72
72
  - lib/tcp-client/configuration.rb
73
73
  - lib/tcp-client/default_configuration.rb
74
74
  - lib/tcp-client/errors.rb
75
- - lib/tcp-client/mixin/io_timeout.rb
76
75
  - lib/tcp-client/mixin/io_with_deadline.rb
77
76
  - lib/tcp-client/ssl_socket.rb
78
77
  - lib/tcp-client/tcp_socket.rb
@@ -1,118 +0,0 @@
1
- # I keep this file for backward compatibility.
2
- # This may be removed in one of the next versions.
3
- # Let me know if you like to use it elsewhere...
4
-
5
- IOTimeoutError = Class.new(IOError) unless defined?(IOTimeoutError)
6
-
7
- module IOTimeoutMixin
8
- def self.included(mod)
9
- im = mod.instance_methods
10
- if im.index(:wait_writable) && im.index(:wait_readable)
11
- mod.include(DeadlineMethods)
12
- else
13
- mod.include(DeadlineIO)
14
- end
15
- end
16
-
17
- def read_with_deadline(nbytes, deadline, exception)
18
- result = ''.b
19
- return result if nbytes.zero?
20
- loop do
21
- junk_size = nbytes - result.bytesize
22
- read =
23
- with_deadline(deadline, exception) do
24
- read_nonblock(junk_size, exception: false)
25
- end
26
- unless read
27
- close
28
- return result
29
- end
30
- result += read
31
- return result if result.bytesize >= nbytes
32
- end
33
- end
34
-
35
- def read(nbytes, timeout: nil, exception: IOTimeoutError)
36
- timeout = timeout.to_f
37
- return read_all(nbytes) { |junk_size| super(junk_size) } if timeout <= 0
38
- deadline = Time.now + timeout
39
- read_all(nbytes) do |junk_size|
40
- with_deadline(deadline, exception) do
41
- read_nonblock(junk_size, exception: false)
42
- end
43
- end
44
- end
45
-
46
- def write(*msgs, timeout: nil, exception: IOTimeoutError)
47
- timeout = timeout.to_f
48
- return write_all(msgs.join.b) { |junk| super(junk) } if timeout <= 0
49
- deadline = Time.now + timeout
50
- write_all(msgs.join.b) do |junk|
51
- with_deadline(deadline, exception) do
52
- write_nonblock(junk, exception: false)
53
- end
54
- end
55
- end
56
-
57
- private
58
-
59
- def read_all(nbytes)
60
- return ''.b if nbytes.zero?
61
- result = ''.b
62
- loop do
63
- unless read = yield(nbytes - result.bytesize)
64
- close
65
- return result
66
- end
67
- result += read
68
- return result if result.bytesize >= nbytes
69
- end
70
- end
71
-
72
- def write_all(data)
73
- return 0 if (size = data.bytesize).zero?
74
- result = 0
75
- loop do
76
- written = yield(data)
77
- result += written
78
- return result if result >= size
79
- data = data.byteslice(written, data.bytesize - written)
80
- end
81
- end
82
-
83
- module DeadlineMethods
84
- private def with_deadline(deadline, exclass)
85
- loop do
86
- case ret = yield
87
- when :wait_writable
88
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
89
- raise(exclass) if wait_writable(remaining_time).nil?
90
- when :wait_readable
91
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
92
- raise(exclass) if wait_readable(remaining_time).nil?
93
- else
94
- return ret
95
- end
96
- end
97
- end
98
- end
99
-
100
- module DeadlineIO
101
- private def with_deadline(deadline, exclass)
102
- loop do
103
- case ret = yield
104
- when :wait_writable
105
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
106
- raise(exclass) if ::IO.select(nil, [self], nil, remaining_time).nil?
107
- when :wait_readable
108
- raise(exclass) if (remaining_time = deadline - Time.now) <= 0
109
- raise(exclass) if ::IO.select([self], nil, nil, remaining_time).nil?
110
- else
111
- return ret
112
- end
113
- end
114
- end
115
- end
116
-
117
- private_constant(:DeadlineMethods, :DeadlineIO)
118
- end