async-io 1.8.0 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/async/io/ssl_socket.rb +3 -0
- data/lib/async/io/stream.rb +46 -49
- data/lib/async/io/version.rb +1 -1
- data/spec/async/io/stream_spec.rb +11 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8d2a5bb8ab12fac26be40774eb239426d8533b68b42d95866884e03fda6e824
|
4
|
+
data.tar.gz: 1cf9d4063d70649b936354195b83bd25eb49ff53b7a76d33178d2b80269cd319
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b58035212d0d4b063e5c511bfce3ded7f02e5e8524e4b0c47d2e654ca447d92f8f65441cd5ab577c413eacfff71e3ec1dd26c224fd72bf18decc00fcd791334
|
7
|
+
data.tar.gz: 3570983e37a2d827b5ead5bc7d0c2b36a2522bb95241ec54334923e999d2a51ec3829649ccd8eae9af1a501695d5f11c9b1d1469f0bb04508a5ccb2b4a0be938
|
data/lib/async/io/ssl_socket.rb
CHANGED
@@ -75,6 +75,9 @@ module Async
|
|
75
75
|
def self.wrap(socket, context)
|
76
76
|
io = @wrapped_klass.new(socket.to_io, context)
|
77
77
|
|
78
|
+
# We detach the socket from the reactor, otherwise it's possible to add the file descriptor to the selector twice, which is bad.
|
79
|
+
socket.reactor = nil
|
80
|
+
|
78
81
|
# This ensures that when the internal IO is closed, it also closes the internal socket:
|
79
82
|
io.sync_close = true
|
80
83
|
|
data/lib/async/io/stream.rb
CHANGED
@@ -24,7 +24,11 @@ require_relative 'generic'
|
|
24
24
|
module Async
|
25
25
|
module IO
|
26
26
|
class Stream
|
27
|
-
|
27
|
+
# The default block size for IO buffers.
|
28
|
+
# BLOCK_SIZE = ENV.fetch('BLOCK_SIZE', 1024*16).to_i
|
29
|
+
BLOCK_SIZE = 1024*8
|
30
|
+
|
31
|
+
def initialize(io, block_size: BLOCK_SIZE, sync: true)
|
28
32
|
@io = io
|
29
33
|
@eof = false
|
30
34
|
|
@@ -45,11 +49,7 @@ module Async
|
|
45
49
|
return '' if size == 0
|
46
50
|
|
47
51
|
if size
|
48
|
-
|
49
|
-
fill_read_buffer until @eof or @read_buffer.size >= size
|
50
|
-
else
|
51
|
-
fill_read_buffer(size - @read_buffer.size) until @eof or @read_buffer.size >= size
|
52
|
-
end
|
52
|
+
fill_read_buffer until @eof or @read_buffer.size >= size
|
53
53
|
else
|
54
54
|
fill_read_buffer until @eof
|
55
55
|
end
|
@@ -68,6 +68,28 @@ module Async
|
|
68
68
|
return consume_read_buffer(size)
|
69
69
|
end
|
70
70
|
|
71
|
+
# Efficiently read data from the stream until encountering pattern.
|
72
|
+
# @param pattern [String] The pattern to match.
|
73
|
+
# @return [String] The contents of the stream up until the pattern, which is consumed but not returned.
|
74
|
+
def read_until(pattern, offset = 0)
|
75
|
+
until index = @read_buffer.index(pattern, offset)
|
76
|
+
offset = @read_buffer.size
|
77
|
+
|
78
|
+
return unless fill_read_buffer
|
79
|
+
end
|
80
|
+
|
81
|
+
matched = @read_buffer.slice!(0, index)
|
82
|
+
@read_buffer.slice!(0, pattern.bytesize)
|
83
|
+
|
84
|
+
return matched
|
85
|
+
end
|
86
|
+
|
87
|
+
def peek
|
88
|
+
until yield(@read_buffer) || @eof
|
89
|
+
fill_read_buffer
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
71
93
|
# Writes `string` to the buffer. When the buffer is full or #sync is true the
|
72
94
|
# buffer is flushed to the underlying `io`.
|
73
95
|
# @param string the string to write to the buffer.
|
@@ -79,7 +101,8 @@ module Async
|
|
79
101
|
@write_buffer << string
|
80
102
|
|
81
103
|
if @write_buffer.size >= @block_size
|
82
|
-
|
104
|
+
syswrite(@write_buffer)
|
105
|
+
@write_buffer.clear
|
83
106
|
end
|
84
107
|
end
|
85
108
|
|
@@ -117,8 +140,8 @@ module Async
|
|
117
140
|
|
118
141
|
# Closes the stream and flushes any unwritten data.
|
119
142
|
def close
|
120
|
-
flush
|
121
|
-
|
143
|
+
flush
|
144
|
+
ensure
|
122
145
|
@io.close
|
123
146
|
end
|
124
147
|
|
@@ -131,41 +154,24 @@ module Async
|
|
131
154
|
|
132
155
|
alias eof eof?
|
133
156
|
|
134
|
-
# Efficiently read data from the stream until encountering pattern.
|
135
|
-
# @param pattern [String] The pattern to match.
|
136
|
-
# @return [String] The contents of the stream up until the pattern, which is consumed but not returned.
|
137
|
-
def read_until(pattern)
|
138
|
-
index = @read_buffer.index(pattern)
|
139
|
-
|
140
|
-
until index
|
141
|
-
offset = @read_buffer.size
|
142
|
-
|
143
|
-
fill_read_buffer
|
144
|
-
|
145
|
-
return if @eof
|
146
|
-
|
147
|
-
index = @read_buffer.index(pattern, offset)
|
148
|
-
end
|
149
|
-
|
150
|
-
matched = @read_buffer.slice!(0, index)
|
151
|
-
@read_buffer.slice!(0, pattern.bytesize)
|
152
|
-
|
153
|
-
return matched
|
154
|
-
end
|
155
|
-
|
156
|
-
def peek
|
157
|
-
until yield(@read_buffer) || @eof
|
158
|
-
fill_read_buffer
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
157
|
private
|
163
158
|
|
164
159
|
# Fills the buffer from the underlying stream.
|
165
|
-
def fill_read_buffer
|
166
|
-
|
167
|
-
|
160
|
+
def fill_read_buffer
|
161
|
+
Async.logger.debug(self){"fill_read_buffer..."}
|
162
|
+
|
163
|
+
# Can we read directly into the buffer? (Ruby doesn't support append, only replace):
|
164
|
+
if chunk = @io.read(@block_size)
|
165
|
+
Async.logger.debug(self){"@io.read -> #{chunk.size} bytes"}
|
166
|
+
@read_buffer << chunk
|
167
|
+
return true
|
168
168
|
end
|
169
|
+
|
170
|
+
Async.logger.debug(self){"@io.read -> #{chunk.inspect}"}
|
171
|
+
|
172
|
+
# We didn't read anything, so we must be at eof:
|
173
|
+
@eof = true
|
174
|
+
return false
|
169
175
|
end
|
170
176
|
|
171
177
|
# Consumes at most `size` bytes from the buffer.
|
@@ -209,15 +215,6 @@ module Async
|
|
209
215
|
|
210
216
|
return written
|
211
217
|
end
|
212
|
-
|
213
|
-
# Read to
|
214
|
-
def sysread(size, buffer)
|
215
|
-
if buffer.empty?
|
216
|
-
@io.read(size, buffer)
|
217
|
-
elsif chunk = @io.read(size)
|
218
|
-
buffer << chunk
|
219
|
-
end
|
220
|
-
end
|
221
218
|
end
|
222
219
|
end
|
223
220
|
end
|
data/lib/async/io/version.rb
CHANGED
@@ -49,6 +49,17 @@ RSpec.describe Async::IO::Stream do
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
+
describe '#read_until' do
|
53
|
+
it "can read a line" do
|
54
|
+
io.write("hello\nworld\n")
|
55
|
+
io.seek(0)
|
56
|
+
|
57
|
+
expect(stream.read_until("\n")).to be == 'hello'
|
58
|
+
expect(stream.read_until("\n")).to be == 'world'
|
59
|
+
expect(stream.read_until("\n")).to be_nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
52
63
|
describe '#flush' do
|
53
64
|
it "should not call write if write buffer is empty" do
|
54
65
|
expect(io).to_not receive(:write)
|
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.8.
|
4
|
+
version: 1.8.1
|
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-04-
|
11
|
+
date: 2018-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|