async-io 1.8.0 → 1.8.1
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/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
|