async-io 0.5.0 → 1.0.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/.travis.yml +11 -9
- data/README.md +7 -7
- data/async-io.gemspec +1 -1
- data/lib/async/io.rb +1 -1
- data/lib/async/io/{address.rb → endpoint.rb} +33 -47
- data/lib/async/io/socket.rb +2 -2
- data/lib/async/io/version.rb +1 -1
- data/spec/async/io/c10k_spec.rb +2 -0
- data/spec/async/io/echo_spec.rb +1 -1
- data/spec/async/io/{address_spec.rb → endpoint_spec.rb} +8 -8
- data/spec/spec_helper.rb +15 -0
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fbd77d42c8f025d30053dc7e421240f1f2c68fa
|
4
|
+
data.tar.gz: 402ee863245252e8e3f19723876301650c9e6439
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dae197ce5e7a47b42b3ec929777ab4baae97182f6e5c3fda6953223c983f1d9cc0f4034c495c12aa6a5e742b520aa138b17633ed667989fc8e714dad6e8a670e
|
7
|
+
data.tar.gz: 3ccb61d3e991fd5d52beabca6e6da9ee834adc637803c42405bd101446ba3dbbc7927119391a14b09605557346715947c5234be66e61fd944332a3984cfbd762
|
data/.travis.yml
CHANGED
@@ -2,16 +2,18 @@ language: ruby
|
|
2
2
|
sudo: false
|
3
3
|
dist: trusty
|
4
4
|
cache: bundler
|
5
|
-
|
6
|
-
- 2.0
|
7
|
-
- 2.1
|
8
|
-
- 2.2
|
9
|
-
- 2.3
|
10
|
-
- 2.4
|
11
|
-
- jruby-head
|
12
|
-
- ruby-head
|
13
|
-
- rbx-3
|
5
|
+
|
14
6
|
matrix:
|
7
|
+
include:
|
8
|
+
- rvm: 2.0
|
9
|
+
- rvm: 2.1
|
10
|
+
- rvm: 2.2
|
11
|
+
- rvm: 2.3
|
12
|
+
- rvm: 2.4
|
13
|
+
- rvm: jruby-head
|
14
|
+
env: JRUBY_OPTS="--debug -X+O"
|
15
|
+
- rvm: ruby-head
|
16
|
+
- rvm: rbx-3
|
15
17
|
allow_failures:
|
16
18
|
- rvm: ruby-head
|
17
19
|
- rvm: jruby-head
|
data/README.md
CHANGED
@@ -31,10 +31,10 @@ Basic echo server (from `spec/async/io/echo_spec.rb`):
|
|
31
31
|
```ruby
|
32
32
|
require 'async/io'
|
33
33
|
|
34
|
-
def echo_server(
|
34
|
+
def echo_server(endpoint)
|
35
35
|
Async::Reactor.run do |task|
|
36
36
|
# This is a synchronous block within the current task:
|
37
|
-
|
37
|
+
endpoint.accept do |client|
|
38
38
|
# This is an asynchronous block within the current reactor:
|
39
39
|
data = client.read(512)
|
40
40
|
|
@@ -46,9 +46,9 @@ def echo_server(server_address)
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
def echo_client(
|
49
|
+
def echo_client(endpoint, data)
|
50
50
|
Async::Reactor.run do |task|
|
51
|
-
|
51
|
+
endpoint.connect do |peer|
|
52
52
|
result = peer.write(data)
|
53
53
|
|
54
54
|
message = peer.read(512)
|
@@ -59,12 +59,12 @@ def echo_client(server_address, data)
|
|
59
59
|
end
|
60
60
|
|
61
61
|
Async::Reactor.run do
|
62
|
-
|
62
|
+
endpoint = Async::IO::Endpoint.tcp('0.0.0.0', 9000)
|
63
63
|
|
64
|
-
server = echo_server(
|
64
|
+
server = echo_server(endpoint)
|
65
65
|
|
66
66
|
5.times.collect do |i|
|
67
|
-
echo_client(
|
67
|
+
echo_client(endpoint, "Hello World #{i}")
|
68
68
|
end.each(&:wait)
|
69
69
|
|
70
70
|
server.stop
|
data/async-io.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
spec.has_rdoc = "yard"
|
18
18
|
|
19
|
-
spec.add_dependency "async", "~> 0
|
19
|
+
spec.add_dependency "async", "~> 1.0"
|
20
20
|
spec.add_development_dependency "async-rspec", "~> 1.1"
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.13"
|
data/lib/async/io.rb
CHANGED
@@ -23,34 +23,37 @@ require 'uri'
|
|
23
23
|
|
24
24
|
module Async
|
25
25
|
module IO
|
26
|
-
|
26
|
+
Address = Addrinfo
|
27
|
+
|
28
|
+
class Endpoint < Struct.new(:specification, :options)
|
27
29
|
include ::Socket::Constants
|
28
30
|
include Comparable
|
29
31
|
|
30
32
|
class << self
|
31
33
|
def parse(string, **options)
|
32
34
|
uri = URI.parse(string)
|
33
|
-
self.
|
35
|
+
self.send(uri.scheme, uri.host, uri.port, **options)
|
34
36
|
end
|
35
37
|
|
36
38
|
def tcp(*args, **options)
|
37
|
-
self.new(
|
39
|
+
self.new(Address.tcp(*args), **options)
|
38
40
|
end
|
39
41
|
|
40
42
|
def udp(*args, **options)
|
41
|
-
self.new(
|
43
|
+
self.new(Address.udp(*args), **options)
|
42
44
|
end
|
43
45
|
|
44
46
|
def unix(*args, **options)
|
45
|
-
self.new(
|
47
|
+
self.new(Address.unix(*args), **options)
|
46
48
|
end
|
47
49
|
|
48
50
|
def each(specifications, &block)
|
49
51
|
specifications.each do |specification|
|
50
52
|
if specification.is_a? self
|
51
53
|
yield specification
|
54
|
+
elsif specification.is_a? Array
|
55
|
+
yield self.send(*specification)
|
52
56
|
else
|
53
|
-
# Perhaps detect options here?
|
54
57
|
yield self.new(specification)
|
55
58
|
end
|
56
59
|
end
|
@@ -61,43 +64,43 @@ module Async
|
|
61
64
|
super(specification, options)
|
62
65
|
end
|
63
66
|
|
64
|
-
def == other
|
65
|
-
self.to_sockaddr == other.to_sockaddr
|
66
|
-
end
|
67
|
-
|
68
|
-
def <=> other
|
69
|
-
self.to_sockaddr <=> other.to_sockaddr
|
70
|
-
end
|
71
|
-
|
72
67
|
def to_sockaddr
|
73
|
-
|
68
|
+
address.to_sockaddr
|
74
69
|
end
|
75
70
|
|
76
71
|
# This is how addresses are internally converted, e.g. within `Socket#sendto`.
|
77
72
|
alias to_str to_sockaddr
|
78
73
|
|
79
|
-
def
|
80
|
-
|
74
|
+
def address
|
75
|
+
@address ||= case specification
|
76
|
+
when Addrinfo
|
77
|
+
specification
|
78
|
+
when ::BasicSocket, BasicSocket
|
79
|
+
specification.local_address
|
80
|
+
else
|
81
|
+
raise ArgumentError, "Not sure how to convert #{specification} into address!"
|
82
|
+
end
|
81
83
|
end
|
82
84
|
|
83
|
-
#
|
84
|
-
|
85
|
-
|
86
|
-
def afamily
|
87
|
-
addrinfo.afamily
|
85
|
+
# SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, etc.
|
86
|
+
def socket_type
|
87
|
+
address.socktype
|
88
88
|
end
|
89
89
|
|
90
|
-
#
|
91
|
-
|
90
|
+
# PF_* eg PF_INET etc, normally identical to AF_* constants.
|
91
|
+
def socket_domain
|
92
|
+
address.afamily
|
93
|
+
end
|
92
94
|
|
93
|
-
#
|
95
|
+
# IPPROTO_TCP, IPPROTO_UDP, IPPROTO_IPX, etc.
|
96
|
+
def socket_protocol
|
97
|
+
address.protocol
|
98
|
+
end
|
94
99
|
|
95
100
|
def bind(&block)
|
96
101
|
case specification
|
97
102
|
when Addrinfo
|
98
103
|
Socket.bind(specification, **options, &block)
|
99
|
-
when Array
|
100
|
-
Socket.bind(Addrinfo.send(*specification), **options, &block)
|
101
104
|
when ::BasicSocket
|
102
105
|
yield Socket.new(specification)
|
103
106
|
when BasicSocket
|
@@ -118,31 +121,14 @@ module Async
|
|
118
121
|
|
119
122
|
def connect(&block)
|
120
123
|
case specification
|
121
|
-
when Addrinfo
|
122
|
-
Socket.connect(
|
124
|
+
when Addrinfo
|
125
|
+
Socket.connect(specification, &block)
|
123
126
|
when ::BasicSocket
|
124
127
|
yield Async::IO.try_convert(specification)
|
125
128
|
when BasicSocket
|
126
129
|
yield specification
|
127
130
|
else
|
128
|
-
raise ArgumentError, "Not sure how to
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
private
|
133
|
-
|
134
|
-
def addrinfo
|
135
|
-
@addrinfo ||= case specification
|
136
|
-
when Addrinfo
|
137
|
-
specification
|
138
|
-
when Array
|
139
|
-
Addrinfo.send(*specification)
|
140
|
-
when ::BasicSocket
|
141
|
-
specification.local_address
|
142
|
-
when BasicSocket
|
143
|
-
specification.local_address
|
144
|
-
else
|
145
|
-
raise ArgumentError, "Not sure how to convert #{specification} into address!"
|
131
|
+
raise ArgumentError, "Not sure how to connect to #{specification}!"
|
146
132
|
end
|
147
133
|
end
|
148
134
|
end
|
data/lib/async/io/socket.rb
CHANGED
@@ -102,10 +102,10 @@ module Async
|
|
102
102
|
# @param remote_address [Addrinfo] The remote address to connect to.
|
103
103
|
# @param local_address [Addrinfo] The local address to bind to before connecting.
|
104
104
|
# @option protcol [Integer] The socket protocol to use.
|
105
|
-
def self.connect(remote_address, local_address = nil,
|
105
|
+
def self.connect(remote_address, local_address = nil, task: Task.current)
|
106
106
|
task.annotate "connecting to #{remote_address.inspect}"
|
107
107
|
|
108
|
-
wrapper = build(remote_address.afamily, remote_address.socktype, protocol) do |socket|
|
108
|
+
wrapper = build(remote_address.afamily, remote_address.socktype, remote_address.protocol) do |socket|
|
109
109
|
socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEADDR, true)
|
110
110
|
|
111
111
|
if local_address
|
data/lib/async/io/version.rb
CHANGED
data/spec/async/io/c10k_spec.rb
CHANGED
data/spec/async/io/echo_spec.rb
CHANGED
@@ -23,7 +23,7 @@ require 'async/io'
|
|
23
23
|
RSpec.describe "echo client/server" do
|
24
24
|
include_context Async::RSpec::Reactor
|
25
25
|
|
26
|
-
let(:server_address) {Async::IO::Address.
|
26
|
+
let(:server_address) {Async::IO::Address.tcp('0.0.0.0', 9000)}
|
27
27
|
|
28
28
|
def echo_server(server_address)
|
29
29
|
Async::Reactor.run do |task|
|
@@ -18,28 +18,28 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
require 'async/io/
|
21
|
+
require 'async/io/endpoint'
|
22
22
|
|
23
|
-
RSpec.describe Async::IO::
|
23
|
+
RSpec.describe Async::IO::Endpoint do
|
24
24
|
include_context Async::RSpec::Reactor
|
25
25
|
|
26
|
-
describe Async::IO::
|
26
|
+
describe Async::IO::Endpoint.tcp('0.0.0.0', 1234) do
|
27
27
|
it "should be a tcp binding" do
|
28
|
-
expect(subject.
|
28
|
+
expect(subject.socket_type).to be == ::Socket::SOCK_STREAM
|
29
29
|
end
|
30
30
|
|
31
31
|
it "should generate valid address" do
|
32
|
-
expect(subject).to be ==
|
32
|
+
expect(subject.address).to be == Async::IO::Address.tcp('0.0.0.0', 1234)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
describe Async::IO::
|
36
|
+
describe Async::IO::Endpoint.new(TCPServer.new('0.0.0.0', 1234)) do
|
37
37
|
it "should be a tcp binding" do
|
38
|
-
expect(subject.
|
38
|
+
expect(subject.socket_type).to be == ::Socket::SOCK_STREAM
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should generate valid address" do
|
42
|
-
expect(subject).to be ==
|
42
|
+
expect(subject.address).to be == Async::IO::Address.tcp('0.0.0.0', 1234)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,21 @@ end
|
|
19
19
|
require "bundler/setup"
|
20
20
|
require "async/io"
|
21
21
|
|
22
|
+
# This is useful for specs, but I hesitate to monkey patch a core class in the library itself.
|
23
|
+
class Addrinfo
|
24
|
+
def == other
|
25
|
+
self.to_s == other.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def != other
|
29
|
+
self.to_s != other.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def <=> other
|
33
|
+
self.to_s <=> other.to_s
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
22
37
|
# Shared rspec helpers:
|
23
38
|
require "async/rspec"
|
24
39
|
|
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: 0.
|
4
|
+
version: 1.0.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: 2017-
|
11
|
+
date: 2017-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0
|
19
|
+
version: '1.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0
|
26
|
+
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: async-rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,8 +95,8 @@ files:
|
|
95
95
|
- Rakefile
|
96
96
|
- async-io.gemspec
|
97
97
|
- lib/async/io.rb
|
98
|
-
- lib/async/io/address.rb
|
99
98
|
- lib/async/io/binary_string.rb
|
99
|
+
- lib/async/io/endpoint.rb
|
100
100
|
- lib/async/io/generic.rb
|
101
101
|
- lib/async/io/protocol/line.rb
|
102
102
|
- lib/async/io/socket.rb
|
@@ -106,9 +106,9 @@ files:
|
|
106
106
|
- lib/async/io/unix_socket.rb
|
107
107
|
- lib/async/io/version.rb
|
108
108
|
- lib/async/io/wrap/tcp.rb
|
109
|
-
- spec/async/io/address_spec.rb
|
110
109
|
- spec/async/io/c10k_spec.rb
|
111
110
|
- spec/async/io/echo_spec.rb
|
111
|
+
- spec/async/io/endpoint_spec.rb
|
112
112
|
- spec/async/io/generic_spec.rb
|
113
113
|
- spec/async/io/protocol/line_spec.rb
|
114
114
|
- spec/async/io/socket_spec.rb
|
@@ -142,9 +142,9 @@ signing_key:
|
|
142
142
|
specification_version: 4
|
143
143
|
summary: Provides support for asynchonous TCP, UDP, UNIX and SSL sockets.
|
144
144
|
test_files:
|
145
|
-
- spec/async/io/address_spec.rb
|
146
145
|
- spec/async/io/c10k_spec.rb
|
147
146
|
- spec/async/io/echo_spec.rb
|
147
|
+
- spec/async/io/endpoint_spec.rb
|
148
148
|
- spec/async/io/generic_spec.rb
|
149
149
|
- spec/async/io/protocol/line_spec.rb
|
150
150
|
- spec/async/io/socket_spec.rb
|