async-io 1.23.3 → 1.24.0
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/generic.rb +5 -3
- data/lib/async/io/stream.rb +19 -1
- data/lib/async/io/version.rb +1 -1
- data/spec/async/io/stream_spec.rb +23 -8
- data/spec/spec_helper.rb +6 -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: c0614be3c203f3e9b8de82215fdacbe3a9bccdcd9b82784af349aa3149d63419
|
4
|
+
data.tar.gz: da66baf1cea7ee3ba1411eee6c09a7eeef5faef39e40ce6459fcd8002df2437b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3624d5fe1177e65b87cb75fdec5eaeac9ef25543d423a66333c6de3b2826f656d0e7acdf5742741b2a7744518baa482f987584829aa6f2ebf140339161bf13be
|
7
|
+
data.tar.gz: d12bdfe724ba95f6f39cbc68bf21b7df0c16537f1c5dd689e70f102609ce6c75502d2cc41478546c9704d42bfdcdafbdc9e63a5cc5cc300ccf08610d4c533f96
|
data/lib/async/io/generic.rb
CHANGED
@@ -23,9 +23,11 @@ require 'forwardable'
|
|
23
23
|
|
24
24
|
module Async
|
25
25
|
module IO
|
26
|
-
# The default block size for IO buffers.
|
27
|
-
|
28
|
-
|
26
|
+
# The default block size for IO buffers. Defaults to 8KB.
|
27
|
+
BLOCK_SIZE = ENV.fetch('ASYNC_IO_BLOCK_SIZE', 1024*8).to_i
|
28
|
+
|
29
|
+
# The maximum read size when appending to IO buffers. Defaults to 8MB.
|
30
|
+
MAXIMUM_READ_SIZE = ENV.fetch('ASYNC_IO_MAXIMUM_READ_SIZE', BLOCK_SIZE * 128 * 8).to_i
|
29
31
|
|
30
32
|
# Convert a Ruby ::IO object to a wrapped instance:
|
31
33
|
def self.try_convert(io, &block)
|
data/lib/async/io/stream.rb
CHANGED
@@ -26,7 +26,19 @@ module Async
|
|
26
26
|
class Stream
|
27
27
|
BLOCK_SIZE = IO::BLOCK_SIZE
|
28
28
|
|
29
|
-
def
|
29
|
+
def self.open(path, mode = "r+", **options)
|
30
|
+
stream = self.new(File.open(path, mode), **options)
|
31
|
+
|
32
|
+
return stream unless block_given?
|
33
|
+
|
34
|
+
begin
|
35
|
+
yield stream
|
36
|
+
ensure
|
37
|
+
stream.close
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(io, block_size: BLOCK_SIZE, maximum_read_size: MAXIMUM_READ_SIZE, sync: true)
|
30
42
|
@io = io
|
31
43
|
@eof = false
|
32
44
|
|
@@ -34,6 +46,7 @@ module Async
|
|
34
46
|
@io.sync = sync
|
35
47
|
|
36
48
|
@block_size = block_size
|
49
|
+
@maximum_read_size = maximum_read_size
|
37
50
|
|
38
51
|
@read_buffer = Buffer.new
|
39
52
|
@write_buffer = Buffer.new
|
@@ -220,6 +233,11 @@ module Async
|
|
220
233
|
|
221
234
|
# Fills the buffer from the underlying stream.
|
222
235
|
def fill_read_buffer(size = @block_size)
|
236
|
+
# We impose a limit because the underlying `read` system call can fail if we request too much data in one go.
|
237
|
+
if size > @maximum_read_size
|
238
|
+
size = @maximum_read_size
|
239
|
+
end
|
240
|
+
|
223
241
|
if @read_buffer.empty? and @io.read_nonblock(size, @read_buffer, exception: false)
|
224
242
|
return true
|
225
243
|
elsif chunk = @io.read_nonblock(size, @input_buffer, exception: false)
|
data/lib/async/io/version.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'async/io/socket'
|
22
|
+
require 'async/clock'
|
22
23
|
|
23
24
|
require_relative 'generic_examples'
|
24
25
|
require_relative 'stream_context'
|
@@ -46,14 +47,6 @@ RSpec.describe Async::IO::Stream do
|
|
46
47
|
it_should_behave_like Async::IO
|
47
48
|
|
48
49
|
describe '#close_read' do
|
49
|
-
let(:sockets) do
|
50
|
-
@sockets = Async::IO::Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM)
|
51
|
-
end
|
52
|
-
|
53
|
-
after do
|
54
|
-
@sockets&.each(&:close)
|
55
|
-
end
|
56
|
-
|
57
50
|
subject {described_class.new(sockets.last)}
|
58
51
|
|
59
52
|
it "can close the reading end of the stream" do
|
@@ -95,6 +88,28 @@ RSpec.describe Async::IO::Stream do
|
|
95
88
|
end
|
96
89
|
end
|
97
90
|
|
91
|
+
context "performance (BLOCK_SIZE: #{Async::IO::BLOCK_SIZE} MAXIMUM_READ_SIZE: #{Async::IO::MAXIMUM_READ_SIZE})" do
|
92
|
+
include_context Async::RSpec::Reactor
|
93
|
+
|
94
|
+
let!(:stream) {described_class.open("/dev/zero")}
|
95
|
+
after {stream.close}
|
96
|
+
|
97
|
+
it "can read data quickly" do |example|
|
98
|
+
data = nil
|
99
|
+
|
100
|
+
duration = Async::Clock.measure do
|
101
|
+
data = stream.read(4*1024**3)
|
102
|
+
end
|
103
|
+
|
104
|
+
size = data.bytesize / 1024**2
|
105
|
+
rate = size / duration
|
106
|
+
|
107
|
+
example.reporter.message "Read #{size.round(2)}MB of data at #{rate.round(2)}MB/s."
|
108
|
+
|
109
|
+
expect(rate).to be > 512
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
98
113
|
context "buffered I/O" do
|
99
114
|
include_context Async::IO::Stream
|
100
115
|
include_context Async::RSpec::Memory
|
data/spec/spec_helper.rb
CHANGED
@@ -4,6 +4,12 @@ require "async/rspec"
|
|
4
4
|
|
5
5
|
require_relative 'addrinfo'
|
6
6
|
|
7
|
+
class RSpec::Core::Formatters::DocumentationFormatter
|
8
|
+
def message(notification)
|
9
|
+
output.puts "#{current_indentation}#{notification.message}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
RSpec.configure do |config|
|
8
14
|
# Enable flags like --only-failures and --next-failure
|
9
15
|
config.example_status_persistence_file_path = ".rspec_status"
|
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.24.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: 2019-
|
11
|
+
date: 2019-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|