tcp-client 0.2.3 → 0.3.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: 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