async-io 1.23.3 → 1.24.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/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
|