async-io 1.16.4 → 1.17.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/.editorconfig +2 -1
- data/.travis.yml +2 -0
- data/lib/async/io/socket.rb +32 -6
- data/lib/async/io/version.rb +1 -1
- data/spec/async/io/generic_spec.rb +3 -1
- data/spec/async/io/socket_spec.rb +13 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/truffle.rb +58 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f254eacfde68b66e406ec00807db18c540f32d899fe4ceece03e39fc0c4df3dd
|
4
|
+
data.tar.gz: e4409d3946bfd916032afd983765f87a344e73afed3c7e83afc947bc5b2459f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39642ae9d92dcf5772cb3df0d067df6acb355a3132efcb60deb535b516a2f47b6ffeb635a521b78eb67e0e34c9bf881f938a5bdc2d5c5f15f652c81245543cba
|
7
|
+
data.tar.gz: 25c54aab50b73e02abba62201c6b3750bea851ba36a6fe81074148bebcc60364f09397882f0fdb759cccba1c60a79e544995b82610f9287f3d7a33eb9e6a0507
|
data/.editorconfig
CHANGED
data/.travis.yml
CHANGED
@@ -13,11 +13,13 @@ matrix:
|
|
13
13
|
- rvm: 2.4
|
14
14
|
- rvm: 2.5
|
15
15
|
- rvm: 2.6
|
16
|
+
- rvm: truffleruby
|
16
17
|
- rvm: jruby-head
|
17
18
|
env: JRUBY_OPTS="--debug -X+O"
|
18
19
|
- rvm: ruby-head
|
19
20
|
- rvm: rbx-3
|
20
21
|
allow_failures:
|
21
22
|
- rvm: ruby-head
|
23
|
+
- rvm: truffleruby
|
22
24
|
- rvm: jruby-head
|
23
25
|
- rvm: rbx-3
|
data/lib/async/io/socket.rb
CHANGED
@@ -41,6 +41,37 @@ module Async
|
|
41
41
|
# This might be thrown by recv_nonblock.
|
42
42
|
return false
|
43
43
|
end
|
44
|
+
|
45
|
+
# Best effort to set *_NODELAY if it makes sense. Swallows errors where possible.
|
46
|
+
def sync=(value)
|
47
|
+
super
|
48
|
+
|
49
|
+
case self.protocol
|
50
|
+
when 0, Socket::IPPROTO_TCP
|
51
|
+
self.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, value ? 1 : 0)
|
52
|
+
else
|
53
|
+
warn "Unsure how to sync=#{value} for #{self.protocol}!"
|
54
|
+
end
|
55
|
+
rescue Errno::EINVAL
|
56
|
+
# On Darwin, sometimes occurs when the connection is not yet fully formed. Empirically, TCP_NODELAY is enabled despite this result.
|
57
|
+
end
|
58
|
+
|
59
|
+
def sync
|
60
|
+
case self.protocol
|
61
|
+
when Socket::IPPROTO_TCP
|
62
|
+
self.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY).bool
|
63
|
+
else
|
64
|
+
true
|
65
|
+
end && super
|
66
|
+
end
|
67
|
+
|
68
|
+
def type
|
69
|
+
self.local_address.socktype
|
70
|
+
end
|
71
|
+
|
72
|
+
def protocol
|
73
|
+
self.local_address.protocol
|
74
|
+
end
|
44
75
|
end
|
45
76
|
|
46
77
|
class BasicSocket < Generic
|
@@ -52,10 +83,6 @@ module Async
|
|
52
83
|
wrap_blocking_method :sendmsg, :sendmsg_nonblock
|
53
84
|
wrap_blocking_method :send, :sendmsg_nonblock, invert: false
|
54
85
|
|
55
|
-
def type
|
56
|
-
self.local_address.socktype
|
57
|
-
end
|
58
|
-
|
59
86
|
include Peer
|
60
87
|
end
|
61
88
|
|
@@ -134,7 +161,6 @@ module Async
|
|
134
161
|
task.annotate "connecting to #{remote_address.inspect}"
|
135
162
|
|
136
163
|
wrapper = build(remote_address.afamily, remote_address.socktype, remote_address.protocol, **options) do |socket|
|
137
|
-
|
138
164
|
if reuse_port
|
139
165
|
socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEADDR, 1)
|
140
166
|
end
|
@@ -142,7 +168,7 @@ module Async
|
|
142
168
|
if local_address
|
143
169
|
socket.bind(local_address.to_sockaddr)
|
144
170
|
end
|
145
|
-
|
171
|
+
|
146
172
|
self.new(socket, task.reactor)
|
147
173
|
end
|
148
174
|
|
data/lib/async/io/version.rb
CHANGED
@@ -25,9 +25,11 @@ require_relative 'generic_examples'
|
|
25
25
|
RSpec.describe Async::IO::Generic do
|
26
26
|
include_context Async::RSpec::Reactor
|
27
27
|
|
28
|
+
CONSOLE_METHODS = [:beep, :cooked, :cooked!, :cursor, :cursor=, :echo=, :echo?,:getch, :getpass, :goto, :iflush, :ioflush, :noecho, :oflush,:pressed?, :raw, :raw!, :winsize, :winsize=]
|
29
|
+
|
28
30
|
it_should_behave_like Async::IO::Generic, [
|
29
31
|
:bytes, :chars, :codepoints, :each, :each_byte, :each_char, :each_codepoint, :each_line, :getbyte, :getc, :gets, :lineno, :lineno=, :lines, :print, :printf, :putc, :puts, :readbyte, :readchar, :readline, :readlines, :ungetbyte, :ungetc
|
30
|
-
]
|
32
|
+
] + CONSOLE_METHODS
|
31
33
|
|
32
34
|
let(:pipe) {IO.pipe}
|
33
35
|
let(:input) {Async::IO::Generic.new(pipe.first)}
|
@@ -71,6 +71,19 @@ RSpec.describe Async::IO::Socket do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
describe '#sync' do
|
75
|
+
it "should set TCP_NODELAY" do
|
76
|
+
address = Async::IO::Address.tcp('127.0.0.1', 0)
|
77
|
+
|
78
|
+
socket = Async::IO::Socket.wrap(::Socket::AF_INET, ::Socket::SOCK_STREAM, ::Socket::IPPROTO_TCP)
|
79
|
+
|
80
|
+
socket.sync = true
|
81
|
+
expect(socket.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY).bool).to be true
|
82
|
+
|
83
|
+
socket.close
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
74
87
|
describe '.pair' do
|
75
88
|
subject{described_class.pair(:UNIX, :STREAM, 0)}
|
76
89
|
|
data/spec/spec_helper.rb
CHANGED
data/spec/truffle.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
class IO
|
5
|
+
def write_nonblock(data, exception: true)
|
6
|
+
ensure_open_and_writable
|
7
|
+
|
8
|
+
data = String data
|
9
|
+
return 0 if data.empty?
|
10
|
+
|
11
|
+
@ibuffer.unseek!(self) unless @sync
|
12
|
+
|
13
|
+
self.nonblock = true
|
14
|
+
|
15
|
+
begin
|
16
|
+
Truffle::POSIX.write_string_nonblock(self, data)
|
17
|
+
rescue Errno::EAGAIN
|
18
|
+
if exception
|
19
|
+
raise EAGAINWaitWritable
|
20
|
+
else
|
21
|
+
return :wait_writable
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class IO::BidirectionalPipe
|
28
|
+
def write_nonblock(*args, **options)
|
29
|
+
@write.write_nonblock(*args, **options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Socket
|
34
|
+
def connect_nonblock(sockaddr, exception: true)
|
35
|
+
fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
|
36
|
+
|
37
|
+
if sockaddr.is_a?(Addrinfo)
|
38
|
+
sockaddr = sockaddr.to_sockaddr
|
39
|
+
end
|
40
|
+
|
41
|
+
status = Truffle::Socket::Foreign.connect(descriptor, sockaddr)
|
42
|
+
|
43
|
+
# There should be a better way to do this than raising an exception!?
|
44
|
+
if Errno.errno == Errno::EISCONN::Errno
|
45
|
+
raise Errno::EISCONN
|
46
|
+
end
|
47
|
+
|
48
|
+
if status < 0
|
49
|
+
if exception
|
50
|
+
Truffle::Socket::Error.write_nonblock('connect(2)')
|
51
|
+
else
|
52
|
+
:wait_writable
|
53
|
+
end
|
54
|
+
else
|
55
|
+
0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
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.17.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-
|
11
|
+
date: 2018-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -152,6 +152,7 @@ files:
|
|
152
152
|
- spec/async/io/wrap/http_rb_spec.rb
|
153
153
|
- spec/async/io/wrap/tcp_spec.rb
|
154
154
|
- spec/spec_helper.rb
|
155
|
+
- spec/truffle.rb
|
155
156
|
homepage: https://github.com/socketry/async-io
|
156
157
|
licenses: []
|
157
158
|
metadata: {}
|
@@ -171,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
171
172
|
version: '0'
|
172
173
|
requirements: []
|
173
174
|
rubyforge_project:
|
174
|
-
rubygems_version: 2.7.
|
175
|
+
rubygems_version: 2.7.8
|
175
176
|
signing_key:
|
176
177
|
specification_version: 4
|
177
178
|
summary: Provides support for asynchonous TCP, UDP, UNIX and SSL sockets.
|
@@ -201,3 +202,4 @@ test_files:
|
|
201
202
|
- spec/async/io/wrap/http_rb_spec.rb
|
202
203
|
- spec/async/io/wrap/tcp_spec.rb
|
203
204
|
- spec/spec_helper.rb
|
205
|
+
- spec/truffle.rb
|