async-io 1.15.5 → 1.16.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 +4 -4
- data/async-io.gemspec +0 -1
- data/lib/async/io/socket.rb +2 -2
- data/lib/async/io/stream.rb +12 -12
- data/lib/async/io/tcp_socket.rb +38 -1
- data/lib/async/io/version.rb +1 -1
- data/spec/async/io/socket_spec.rb +10 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11d4123b62b4c9d36348dffe2ce2e450924d491db1b3bd4f4ded739140637300
|
4
|
+
data.tar.gz: f707c236c48b1169dc1d26fe9101782c7c11ab26c9c05a6e5cd19bfa784183ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8f33cc994bf02d7ece78d249bf85418c9f5de2c079f49053cb4f7534e5d04b12f40a468fc7ef095c0cbacd04c1fe37291726b20c07f2f34c52453ac9b8ce4cb
|
7
|
+
data.tar.gz: 65424003ca8e5904e4984af6bf558f8e7378e873f6f1ec018aea0669187786ef3d348c4c546a5ecb8e80edc526eb41eb5ac09242f714263fec1badacad3d9cf9
|
data/async-io.gemspec
CHANGED
@@ -14,7 +14,6 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.executables = spec.files.grep(%r{^bin/}).map{|f| File.basename(f)}
|
15
15
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
16
|
spec.require_paths = ["lib"]
|
17
|
-
spec.has_rdoc = "yard"
|
18
17
|
|
19
18
|
spec.add_dependency "async", "~> 1.3"
|
20
19
|
spec.add_development_dependency "async-rspec", "~> 1.10"
|
data/lib/async/io/socket.rb
CHANGED
@@ -123,7 +123,7 @@ module Async
|
|
123
123
|
# @param local_address [Addrinfo] The local address to bind to before connecting.
|
124
124
|
# @option protcol [Integer] The socket protocol to use.
|
125
125
|
def self.connect(remote_address, local_address = nil, reuse_port: false, task: Task.current, **options)
|
126
|
-
|
126
|
+
Async.logger.debug(self) {"Connecting to #{remote_address.inspect}"}
|
127
127
|
|
128
128
|
task.annotate "connecting to #{remote_address.inspect}"
|
129
129
|
|
@@ -140,7 +140,7 @@ module Async
|
|
140
140
|
begin
|
141
141
|
wrapper.connect(remote_address.to_sockaddr)
|
142
142
|
task.annotate "connected to #{remote_address.inspect}"
|
143
|
-
rescue
|
143
|
+
rescue Exception
|
144
144
|
wrapper.close
|
145
145
|
raise
|
146
146
|
end
|
data/lib/async/io/stream.rb
CHANGED
@@ -79,10 +79,12 @@ module Async
|
|
79
79
|
return consume_read_buffer(size)
|
80
80
|
end
|
81
81
|
|
82
|
+
alias readpartial read_partial
|
83
|
+
|
82
84
|
# Efficiently read data from the stream until encountering pattern.
|
83
85
|
# @param pattern [String] The pattern to match.
|
84
86
|
# @return [String] The contents of the stream up until the pattern, which is consumed but not returned.
|
85
|
-
def read_until(pattern, offset = 0)
|
87
|
+
def read_until(pattern, offset = 0, chomp: true)
|
86
88
|
until index = @read_buffer.index(pattern, offset)
|
87
89
|
offset = @read_buffer.size
|
88
90
|
|
@@ -90,7 +92,7 @@ module Async
|
|
90
92
|
end
|
91
93
|
|
92
94
|
@read_buffer.freeze
|
93
|
-
matched = @read_buffer.byteslice(0, index)
|
95
|
+
matched = @read_buffer.byteslice(0, index+(chomp ? 0 : pattern.bytesize))
|
94
96
|
@read_buffer = @read_buffer.byteslice(index+pattern.bytesize, @read_buffer.bytesize)
|
95
97
|
|
96
98
|
return matched
|
@@ -120,14 +122,14 @@ module Async
|
|
120
122
|
|
121
123
|
return string.bytesize
|
122
124
|
end
|
123
|
-
|
125
|
+
|
124
126
|
# Writes `string` to the stream and returns self.
|
125
127
|
def <<(string)
|
126
128
|
write(string)
|
127
129
|
|
128
130
|
return self
|
129
131
|
end
|
130
|
-
|
132
|
+
|
131
133
|
# Flushes buffered data to the stream.
|
132
134
|
def flush
|
133
135
|
unless @write_buffer.empty?
|
@@ -135,13 +137,11 @@ module Async
|
|
135
137
|
@write_buffer.clear
|
136
138
|
end
|
137
139
|
end
|
138
|
-
|
139
|
-
def gets(separator =
|
140
|
-
|
141
|
-
|
142
|
-
read_until(separator)
|
140
|
+
|
141
|
+
def gets(separator = $/, **options)
|
142
|
+
read_until(separator, **options)
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
def puts(*args, separator: $/)
|
146
146
|
args.each do |arg|
|
147
147
|
@write_buffer << arg << separator
|
@@ -171,7 +171,7 @@ module Async
|
|
171
171
|
@io.close
|
172
172
|
end
|
173
173
|
end
|
174
|
-
|
174
|
+
|
175
175
|
# Returns true if the stream is at file which means there is no more data to be read.
|
176
176
|
def eof?
|
177
177
|
fill_read_buffer if !@eof && @read_buffer.empty?
|
@@ -203,7 +203,7 @@ module Async
|
|
203
203
|
return false
|
204
204
|
end
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
# Consumes at most `size` bytes from the buffer.
|
208
208
|
# @param size [Integer|nil] The amount of data to consume. If nil, consume entire buffer.
|
209
209
|
def consume_read_buffer(size = nil)
|
data/lib/async/io/tcp_socket.rb
CHANGED
@@ -28,6 +28,32 @@ module Async
|
|
28
28
|
class TCPSocket < IPSocket
|
29
29
|
wraps ::TCPSocket
|
30
30
|
|
31
|
+
class StreamWrapper
|
32
|
+
def initialize(io)
|
33
|
+
@io = io
|
34
|
+
end
|
35
|
+
|
36
|
+
def sync= value
|
37
|
+
@io.sync = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def close
|
41
|
+
@io.close
|
42
|
+
end
|
43
|
+
|
44
|
+
def read(*args)
|
45
|
+
@io.sysread(*args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def write(*args)
|
49
|
+
@io.syswrite(*args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def flush
|
53
|
+
@io.flush
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
31
57
|
def initialize(remote_host, remote_port = nil, local_host = nil, local_port = nil)
|
32
58
|
if remote_host.is_a? ::TCPSocket
|
33
59
|
super(remote_host)
|
@@ -38,6 +64,7 @@ module Async
|
|
38
64
|
# We do this unusual dance to avoid leaking an "open" socket instance.
|
39
65
|
socket = Socket.connect(remote_address, local_address)
|
40
66
|
fd = socket.fcntl(Fcntl::F_DUPFD)
|
67
|
+
Async.logger.debug(self) {"Connected to #{remote_address.inspect}: #{fd}"}
|
41
68
|
socket.close
|
42
69
|
|
43
70
|
super(::TCPSocket.for_fd(fd))
|
@@ -46,7 +73,7 @@ module Async
|
|
46
73
|
# super(::TCPSocket.new(remote_host, remote_port, local_host, local_port))
|
47
74
|
end
|
48
75
|
|
49
|
-
@buffer = Stream.new(self)
|
76
|
+
@buffer = Stream.new(StreamWrapper.new(self))
|
50
77
|
end
|
51
78
|
|
52
79
|
class << self
|
@@ -58,6 +85,16 @@ module Async
|
|
58
85
|
attr :buffer
|
59
86
|
|
60
87
|
def_delegators :@buffer, :gets, :puts, :flush
|
88
|
+
|
89
|
+
def write(*)
|
90
|
+
@buffer.flush
|
91
|
+
|
92
|
+
super
|
93
|
+
end
|
94
|
+
|
95
|
+
def read(size)
|
96
|
+
@buffer.read_partial(size)
|
97
|
+
end
|
61
98
|
end
|
62
99
|
|
63
100
|
# Asynchronous TCP server wrappper.
|
data/lib/async/io/version.rb
CHANGED
@@ -39,6 +39,16 @@ RSpec.describe Async::IO::Socket do
|
|
39
39
|
Async::IO::Socket.connect(address)
|
40
40
|
end.to raise_error(Errno::ECONNREFUSED)
|
41
41
|
end
|
42
|
+
|
43
|
+
it "should close the socket when interrupted by a timeout" do
|
44
|
+
wrapper = double()
|
45
|
+
expect(Async::IO::Socket).to receive(:build).and_return(wrapper)
|
46
|
+
expect(wrapper).to receive(:connect).and_raise Async::TimeoutError
|
47
|
+
expect(wrapper).to receive(:close)
|
48
|
+
expect do
|
49
|
+
Async::IO::Socket.connect(address)
|
50
|
+
end.to raise_error(Async::TimeoutError)
|
51
|
+
end
|
42
52
|
end
|
43
53
|
|
44
54
|
describe '#bind' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-io
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -168,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
168
|
version: '0'
|
169
169
|
requirements: []
|
170
170
|
rubyforge_project:
|
171
|
-
rubygems_version: 2.7.
|
171
|
+
rubygems_version: 2.7.7
|
172
172
|
signing_key:
|
173
173
|
specification_version: 4
|
174
174
|
summary: Provides support for asynchonous TCP, UDP, UNIX and SSL sockets.
|