tcp-client 0.0.6 → 0.0.8

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: 9a5a96328918c653aaec2296d19a7434b65c8801f3a1132a152dcd66326bc9ce
4
- data.tar.gz: 5add4cd9d2607a90522b14c04a8b9d60a27bcad30c0f56212aba5df6c5036ac9
3
+ metadata.gz: f139f1f90fcb6d8c32a0d0fab85b4c96eab70b2a08845e9cdb26c5de8acfd184
4
+ data.tar.gz: f703e1c0c6f5edb4d732284ba983e31820c1e116cff1329cb7458a642b4ec1af
5
5
  SHA512:
6
- metadata.gz: 859acc902ed173236fac760ce2edbbda4353bf7fb438ecdb3856bdba3076a464a34f542458abc5b1fb2ec157b4f3ab007e0eb67123c551f1b6abedc6f810d978
7
- data.tar.gz: 36b9c267842f00e2d6181d2523b84b776528b7d754fb4eb378fbdb4fc8d33fbb43ac7b9faf5ff613cf34c4687cc2eab74eaff04601fa72196efe3787d622dc7d
6
+ metadata.gz: a19cf4e0ba023fd6a52a7470d1304b6718250c1dc28b49cefa07dc6c1fca6c52d35797bd6e769a80cd9d96feba09d48ebfcbc45273b2718f2fea8fda1de6d749
7
+ data.tar.gz: 1e0444b2cf3169b4d3e31af9ea072f0c44a98c88983f8f657f7917e1d4ee7d245599d7a640183acbb7bcbded8a319f2eed677c4f3aca8bdd15138c04acd13895
@@ -15,7 +15,7 @@ class TCPClient
15
15
 
16
16
  class NotConnected < SocketError
17
17
  def self.raise!(which)
18
- raise(self, format('client not connected - %s', which), caller(1))
18
+ raise(self, "client not connected - #{which}", caller(1))
19
19
  end
20
20
  end
21
21
 
@@ -25,11 +25,9 @@ class TCPClient
25
25
  addr = Address.new(addr)
26
26
  client = new
27
27
  client.connect(addr, configuration)
28
- return yield(client) if block_given?
29
- client, ret = nil, client
30
- ret
28
+ block_given? ? yield(client) : client
31
29
  ensure
32
- client.close if client
30
+ client&.close if block_given?
33
31
  end
34
32
 
35
33
  attr_reader :address
@@ -47,7 +45,9 @@ class TCPClient
47
45
  NoOpenSSL.raise! if configuration.ssl? && !defined?(SSLSocket)
48
46
  @address = Address.new(addr)
49
47
  @socket = TCPSocket.new(@address, configuration, Timeout)
50
- @socket = SSLSocket.new(@socket, @address, configuration, Timeout) if configuration.ssl?
48
+ configuration.ssl? && @socket = SSLSocket.new(
49
+ @socket, @address, configuration, Timeout
50
+ )
51
51
  @write_timeout = configuration.write_timeout
52
52
  @read_timeout = configuration.read_timeout
53
53
  self
@@ -55,7 +55,7 @@ class TCPClient
55
55
 
56
56
  def close
57
57
  socket, @socket = @socket, nil
58
- socket.close if socket
58
+ socket&.close
59
59
  self
60
60
  rescue IOError
61
61
  self
@@ -66,11 +66,13 @@ class TCPClient
66
66
  end
67
67
 
68
68
  def read(nbytes, timeout: @read_timeout)
69
- closed? ? NotConnected.raise!(self) : @socket.read(nbytes, timeout: timeout, exception: Timeout)
69
+ NotConnected.raise!(self) if closed?
70
+ @socket.read(nbytes, timeout: timeout, exception: Timeout)
70
71
  end
71
72
 
72
73
  def write(*msg, timeout: @write_timeout)
73
- closed? ? NotConnected.raise!(self) : @socket.write(*msg, timeout: timeout, exception: Timeout)
74
+ NotConnected.raise!(self) if closed?
75
+ @socket.write(*msg, timeout: timeout, exception: Timeout)
74
76
  end
75
77
 
76
78
  def flush
@@ -68,7 +68,7 @@ class TCPClient
68
68
  private
69
69
 
70
70
  def seconds(value)
71
- value && value > 0 ? value : nil
71
+ value&.positive? ? value : nil
72
72
  end
73
73
  end
74
74
  end
@@ -3,7 +3,11 @@ IOTimeoutError = Class.new(IOError) unless defined?(IOTimeoutError)
3
3
  module IOTimeoutMixin
4
4
  def self.included(mod)
5
5
  im = mod.instance_methods
6
- mod.include(im.index(:wait_writable) && im.index(:wait_readable) ? WithDeadlineMethods : WidthDeadlineIO)
6
+ if im.index(:wait_writable) && im.index(:wait_readable)
7
+ mod.include(DeadlineMethods)
8
+ else
9
+ mod.include(DeadlineIO)
10
+ end
7
11
  end
8
12
 
9
13
  def read(nbytes, timeout: nil, exception: IOTimeoutError)
@@ -11,7 +15,9 @@ module IOTimeoutMixin
11
15
  return read_all(nbytes){ |junk_size| super(junk_size) } if timeout <= 0
12
16
  deadline = Time.now + timeout
13
17
  read_all(nbytes) do |junk_size|
14
- with_deadline(deadline, exception){ read_nonblock(junk_size, exception: false) }
18
+ with_deadline(deadline, exception) do
19
+ read_nonblock(junk_size, exception: false)
20
+ end
15
21
  end
16
22
  end
17
23
 
@@ -20,7 +26,9 @@ module IOTimeoutMixin
20
26
  return write_all(msgs.join){ |junk| super(junk) } if timeout <= 0
21
27
  deadline = Time.now + timeout
22
28
  write_all(msgs.join) do |junk|
23
- with_deadline(deadline, exception){ write_nonblock(junk, exception: false) }
29
+ with_deadline(deadline, exception) do
30
+ write_nonblock(junk, exception: false)
31
+ end
24
32
  end
25
33
  end
26
34
 
@@ -50,18 +58,18 @@ module IOTimeoutMixin
50
58
  end
51
59
  end
52
60
 
53
- module WithDeadlineMethods
61
+ module DeadlineMethods
54
62
  private
55
63
 
56
64
  def with_deadline(deadline, exclass)
57
65
  loop do
58
66
  case ret = yield
59
67
  when :wait_writable
60
- remaining_time = deadline - Time.now
61
- raise(exclass) if remaining_time <= 0 || wait_writable(remaining_time).nil?
68
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
69
+ raise(exclass) if wait_writable(remaining_time).nil?
62
70
  when :wait_readable
63
- remaining_time = deadline - Time.now
64
- raise(exclass) if remaining_time <= 0 || wait_readable(remaining_time).nil?
71
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
72
+ raise(exclass) if wait_readable(remaining_time).nil?
65
73
  else
66
74
  return ret
67
75
  end
@@ -69,18 +77,18 @@ module IOTimeoutMixin
69
77
  end
70
78
  end
71
79
 
72
- module WidthDeadlineIO
80
+ module DeadlineIO
73
81
  private
74
82
 
75
83
  def with_deadline(deadline, exclass)
76
84
  loop do
77
85
  case ret = yield
78
86
  when :wait_writable
79
- remaining_time = deadline - Time.now
80
- raise(exclass) if remaining_time <= 0 || ::IO.select(nil, [self], nil, remaining_time).nil?
87
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
88
+ raise(exclass) if ::IO.select(nil, [self], nil, remaining_time).nil?
81
89
  when :wait_readable
82
- remaining_time = deadline - Time.now
83
- raise(exclass) if remaining_time <= 0 || ::IO.select([self], nil, nil, remaining_time).nil?
90
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
91
+ raise(exclass) if ::IO.select([self], nil, nil, remaining_time).nil?
84
92
  else
85
93
  return ret
86
94
  end
@@ -88,5 +96,5 @@ module IOTimeoutMixin
88
96
  end
89
97
  end
90
98
 
91
- private_constant :WithDeadlineMethods, :WidthDeadlineIO
99
+ private_constant :DeadlineMethods, :DeadlineIO
92
100
  end
@@ -31,7 +31,13 @@ class TCPClient
31
31
 
32
32
  def connect_to(address, check, timeout, exception)
33
33
  self.hostname = address.hostname
34
- timeout ? with_deadline(Time.now + timeout, exception){ connect_nonblock(exception: false) } : connect
34
+ if timeout
35
+ with_deadline(Time.now + timeout, exception) do
36
+ connect_nonblock(exception: false)
37
+ end
38
+ else
39
+ connect
40
+ end
35
41
  post_connection_check(address.hostname) if check
36
42
  end
37
43
  end
@@ -14,9 +14,13 @@ class TCPClient
14
14
  private
15
15
 
16
16
  def connect_to(address, timeout, exception)
17
- addr = ::Socket.pack_sockaddr_in(address.addrinfo.ip_port, address.addrinfo.ip_address)
17
+ addr = ::Socket.pack_sockaddr_in(
18
+ address.addrinfo.ip_port, address.addrinfo.ip_address
19
+ )
18
20
  return connect(addr) unless timeout
19
- with_deadline(Time.now + timeout, exception){ connect_nonblock(addr, exception: false) }
21
+ with_deadline(Time.now + timeout, exception) do
22
+ connect_nonblock(addr, exception: false)
23
+ end
20
24
  end
21
25
 
22
26
  def configure(configuration)
@@ -1,3 +1,3 @@
1
1
  class TCPClient
2
- VERSION = '0.0.6'.freeze
2
+ VERSION = '0.0.8'.freeze
3
3
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rake/testtask'
3
5
 
@@ -8,5 +10,5 @@ Rake::TestTask.new(:test) do |t|
8
10
  end
9
11
 
10
12
  task :default do
11
- exec('rake -T')
13
+ exec("#{$0} --tasks")
12
14
  end
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../lib/tcp-client/version', __FILE__)
3
+ require_relative './lib/tcp-client/version'
4
4
 
5
5
  GemSpec = Gem::Specification.new do |spec|
6
6
  spec.name = 'tcp-client'
7
7
  spec.version = TCPClient::VERSION
8
8
  spec.summary = 'A TCP client implementation with working timeout support.'
9
- spec.description = <<~EOS
9
+ spec.description = <<~DESCRIPTION
10
10
  This gem implements a TCP client with (optional) SSL support. The
11
11
  motivation of this project is the need to have a _really working_
12
12
  easy to use client which can handle time limits correctly. Unlike
13
13
  other implementations this client respects given/configurable time
14
14
  limits for each method (`connect`, `read`, `write`).
15
- EOS
15
+ DESCRIPTION
16
16
  spec.author = 'Mike Blumtritt'
17
17
  spec.email = 'mike.blumtritt@invision.de'
18
18
  spec.homepage = 'https://github.com/mblumtritt/tcp-client'
@@ -20,12 +20,12 @@ GemSpec = Gem::Specification.new do |spec|
20
20
  spec.rubyforge_project = spec.name
21
21
 
22
22
  spec.add_development_dependency 'bundler'
23
- spec.add_development_dependency 'rake'
24
23
  spec.add_development_dependency 'minitest'
24
+ spec.add_development_dependency 'rake'
25
25
 
26
26
  spec.platform = Gem::Platform::RUBY
27
- spec.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
28
27
  spec.required_ruby_version = '>= 2.5.0'
28
+ spec.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
29
29
 
30
30
  spec.require_paths = %w[lib]
31
31
 
@@ -33,6 +33,5 @@ GemSpec = Gem::Specification.new do |spec|
33
33
  spec.test_files = all_files.grep(%r{^(spec|test)/})
34
34
  spec.files = all_files - spec.test_files
35
35
 
36
- spec.has_rdoc = false
37
36
  spec.extra_rdoc_files = %w[README.md]
38
37
  end
@@ -40,24 +40,30 @@ class TCPClientTest < Test
40
40
  end
41
41
  end
42
42
 
43
+ def with_dummy_server(port)
44
+ # this server will never receive or send any data
45
+ server = TCPServer.new('localhost', port)
46
+ ensure
47
+ server&.close
48
+ end
49
+
43
50
  def test_connected_state
44
- server = TCPServer.new(1234)
45
- TCPClient.open('localhost:1234', TCPClient::Configuration.new) do |subject|
46
- refute(subject.closed?)
47
- assert_equal('localhost:1234', subject.to_s)
48
- refute_nil(subject.address)
49
- address_when_opened = subject.address
50
- assert_equal('localhost:1234', subject.address.to_s)
51
- assert_equal('localhost', subject.address.hostname)
52
- assert_instance_of(Addrinfo, subject.address.addrinfo)
53
- assert_same(1234, subject.address.addrinfo.ip_port)
51
+ with_dummy_server(1234) do
52
+ TCPClient.open('localhost:1234') do |subject|
53
+ refute(subject.closed?)
54
+ assert_equal('localhost:1234', subject.to_s)
55
+ refute_nil(subject.address)
56
+ address_when_opened = subject.address
57
+ assert_equal('localhost:1234', subject.address.to_s)
58
+ assert_equal('localhost', subject.address.hostname)
59
+ assert_instance_of(Addrinfo, subject.address.addrinfo)
60
+ assert_same(1234, subject.address.addrinfo.ip_port)
54
61
 
55
- subject.close
56
- assert(subject.closed?)
57
- assert_same(address_when_opened, subject.address)
62
+ subject.close
63
+ assert(subject.closed?)
64
+ assert_same(address_when_opened, subject.address)
65
+ end
58
66
  end
59
- ensure
60
- server.close if server
61
67
  end
62
68
 
63
69
  def check_read_write_timeout(addr, timeout)
@@ -66,7 +72,7 @@ class TCPClientTest < Test
66
72
  start_time = nil
67
73
  assert_raises(TCPClient::Timeout) do
68
74
  start_time = Time.now
69
- # we need to send 1MB to avoid any TCP stack buffering
75
+ # send 1MB to avoid any TCP stack buffering
70
76
  subject.write('?' * (1024 * 1024), timeout: timeout)
71
77
  end
72
78
  assert_in_delta(timeout, Time.now - start_time, 0.02)
@@ -79,32 +85,30 @@ class TCPClientTest < Test
79
85
  end
80
86
 
81
87
  def test_read_write_timeout
82
- server = TCPServer.new(1235) # this server will never read/write client data
83
- [0.5, 1, 1.5].each do |timeout|
84
- check_read_write_timeout(':1235', timeout)
88
+ with_dummy_server(1235) do
89
+ [0.5, 1, 1.5].each do |timeout|
90
+ check_read_write_timeout('localhost:1235', timeout)
91
+ end
85
92
  end
86
- ensure
87
- server.close if server
88
93
  end
89
94
 
90
- def check_connect_timeout(addr, config, timeout)
95
+ def check_connect_timeout(addr, config)
91
96
  start_time = nil
92
97
  assert_raises(TCPClient::Timeout) do
93
98
  start_time = Time.now
94
99
  TCPClient.new.connect(addr, config)
95
100
  end
96
- assert_in_delta(timeout, Time.now - start_time, 0.02)
101
+ assert_in_delta(config.connect_timeout, Time.now - start_time, 0.02)
97
102
  end
98
103
 
99
104
  def test_connect_ssl_timeout
100
- server = TCPServer.new(1236)
101
- config = TCPClient::Configuration.new
102
- config.ssl = true
103
- [0.5, 1, 1.5].each do |timeout|
104
- config.timeout = timeout
105
- check_connect_timeout('localhost:1236', config, timeout)
105
+ with_dummy_server(1236) do
106
+ config = TCPClient::Configuration.new
107
+ config.ssl = true
108
+ [0.5, 1, 1.5].each do |timeout|
109
+ config.timeout = timeout
110
+ check_connect_timeout('localhost:1236', config)
111
+ end
106
112
  end
107
- ensure
108
- server.close if server
109
113
  end
110
114
  end
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.0.6
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-21 00:00:00.000000000 Z
11
+ date: 2018-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: minitest
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -104,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  version: 1.3.6
105
105
  requirements: []
106
106
  rubyforge_project: tcp-client
107
- rubygems_version: 2.7.3
107
+ rubygems_version: 2.7.7
108
108
  signing_key:
109
109
  specification_version: 4
110
110
  summary: A TCP client implementation with working timeout support.