io-endpoint 0.14.0 → 0.15.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
- checksums.yaml.gz.sig +0 -0
- data/lib/io/endpoint/address_endpoint.rb +6 -6
- data/lib/io/endpoint/bound_endpoint.rb +6 -6
- data/lib/io/endpoint/composite_endpoint.rb +4 -4
- data/lib/io/endpoint/connected_endpoint.rb +6 -6
- data/lib/io/endpoint/generic.rb +11 -6
- data/lib/io/endpoint/host_endpoint.rb +4 -4
- data/lib/io/endpoint/shared_endpoint.rb +2 -2
- data/lib/io/endpoint/socket_endpoint.rb +2 -2
- data/lib/io/endpoint/ssl_endpoint.rb +3 -3
- data/lib/io/endpoint/unix_endpoint.rb +2 -2
- data/lib/io/endpoint/version.rb +1 -1
- data/lib/io/endpoint/wrapper.rb +47 -33
- data/license.md +1 -1
- data.tar.gz.sig +0 -0
- metadata +3 -8
- metadata.gz.sig +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52e4f0d4b8e0e46f2ad47c655f0b841fd9cbd4b26165139a5260546f5baa5167
|
4
|
+
data.tar.gz: a86e657651e34a15f300d67e1df05b7ef29b6e5624b61c2bc06df57269f005dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b33453871ae938df8dc7c21bf5eb2db870a7433ec61015dc3aa0b1f1f572ff36f3bd46c3f447e53ee58891c4570215bcf14c8c06010433d6dcaf1956b7034659
|
7
|
+
data.tar.gz: 8a1143e06da6a04216f6e7a5a9af31530b3867e89771e739e28e67d68987dbb9be7e587bba86cfd934f7e80f85043f4cbfb10119dd11521bac4747d70708e840
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2023, by Samuel Williams.
|
4
|
+
# Copyright, 2023-2025, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
6
|
+
require "socket"
|
7
7
|
|
8
|
-
require_relative
|
9
|
-
require_relative
|
8
|
+
require_relative "generic"
|
9
|
+
require_relative "wrapper"
|
10
10
|
|
11
11
|
module IO::Endpoint
|
12
12
|
class AddressEndpoint < Generic
|
@@ -37,13 +37,13 @@ module IO::Endpoint
|
|
37
37
|
# @yield {|socket| ...} An optional block which will be passed the socket.
|
38
38
|
# @parameter socket [Socket] The socket which has been bound.
|
39
39
|
# @return [Array(Socket)] the bound socket
|
40
|
-
def bind(wrapper =
|
40
|
+
def bind(wrapper = self.wrapper, &block)
|
41
41
|
[wrapper.bind(@address, **@options, &block)]
|
42
42
|
end
|
43
43
|
|
44
44
|
# Connects a socket to the given address. If a block is given, the socket will be automatically closed when the block exits.
|
45
45
|
# @return [Socket] the connected socket
|
46
|
-
def connect(wrapper =
|
46
|
+
def connect(wrapper = self.wrapper, &block)
|
47
47
|
wrapper.connect(@address, **@options, &block)
|
48
48
|
end
|
49
49
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2024, by Samuel Williams.
|
4
|
+
# Copyright, 2024-2025, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
6
|
+
require_relative "generic"
|
7
|
+
require_relative "composite_endpoint"
|
8
|
+
require_relative "address_endpoint"
|
9
9
|
|
10
10
|
module IO::Endpoint
|
11
11
|
class BoundEndpoint < Generic
|
@@ -62,10 +62,10 @@ module IO::Endpoint
|
|
62
62
|
"\#<#{self.class} #{@sockets.size} bound sockets for #{@endpoint}>"
|
63
63
|
end
|
64
64
|
|
65
|
-
def bind(wrapper =
|
65
|
+
def bind(wrapper = self.wrapper, &block)
|
66
66
|
@sockets.map do |server|
|
67
67
|
if block_given?
|
68
|
-
wrapper.
|
68
|
+
wrapper.schedule do
|
69
69
|
yield server
|
70
70
|
end
|
71
71
|
else
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2023-
|
4
|
+
# Copyright, 2023-2025, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "generic"
|
7
7
|
|
8
8
|
module IO::Endpoint
|
9
9
|
# A composite endpoint is a collection of endpoints that are used in order.
|
@@ -44,7 +44,7 @@ module IO::Endpoint
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def connect(wrapper =
|
47
|
+
def connect(wrapper = self.wrapper, &block)
|
48
48
|
last_error = nil
|
49
49
|
|
50
50
|
@endpoints.each do |endpoint|
|
@@ -57,7 +57,7 @@ module IO::Endpoint
|
|
57
57
|
raise last_error
|
58
58
|
end
|
59
59
|
|
60
|
-
def bind(wrapper =
|
60
|
+
def bind(wrapper = self.wrapper, &block)
|
61
61
|
if block_given?
|
62
62
|
@endpoints.each do |endpoint|
|
63
63
|
endpoint.bind(&block)
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2024, by Samuel Williams.
|
4
|
+
# Copyright, 2024-2025, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
6
|
+
require_relative "generic"
|
7
|
+
require_relative "composite_endpoint"
|
8
|
+
require_relative "socket_endpoint"
|
9
9
|
|
10
|
-
require
|
10
|
+
require "openssl"
|
11
11
|
|
12
12
|
module IO::Endpoint
|
13
13
|
class ConnectedEndpoint < Generic
|
@@ -41,7 +41,7 @@ module IO::Endpoint
|
|
41
41
|
AddressEndpoint.new(socket.to_io.remote_address, **options)
|
42
42
|
end
|
43
43
|
|
44
|
-
def connect(wrapper =
|
44
|
+
def connect(wrapper = self.wrapper, &block)
|
45
45
|
if block_given?
|
46
46
|
yield @socket
|
47
47
|
else
|
data/lib/io/endpoint/generic.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2023-
|
4
|
+
# Copyright, 2023-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
# require_relative 'address'
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require "uri"
|
8
|
+
require "socket"
|
9
9
|
|
10
10
|
module IO::Endpoint
|
11
11
|
Address = Addrinfo
|
@@ -64,21 +64,21 @@ module IO::Endpoint
|
|
64
64
|
# @yields {|socket| ...} An optional block which will be passed the socket.
|
65
65
|
# @parameter socket [Socket] The socket which has been bound.
|
66
66
|
# @returns [Array(Socket)] the bound socket
|
67
|
-
def bind(wrapper =
|
67
|
+
def bind(wrapper = self.wrapper, &block)
|
68
68
|
raise NotImplementedError
|
69
69
|
end
|
70
70
|
|
71
71
|
# Connects a socket to the given address. If a block is given, the socket will be automatically closed when the block exits.
|
72
72
|
# @parameter wrapper [Wrapper] The wrapper to use for connecting.
|
73
73
|
# @return [Socket] the connected socket
|
74
|
-
def connect(wrapper =
|
74
|
+
def connect(wrapper = self.wrapper, &block)
|
75
75
|
raise NotImplementedError
|
76
76
|
end
|
77
77
|
|
78
78
|
# Bind and accept connections on the given address.
|
79
79
|
# @parameter wrapper [Wrapper] The wrapper to use for accepting connections.
|
80
80
|
# @yields [Socket] The accepted socket.
|
81
|
-
def accept(wrapper =
|
81
|
+
def accept(wrapper = self.wrapper, &block)
|
82
82
|
bind(wrapper) do |server|
|
83
83
|
wrapper.accept(server, **@options, &block)
|
84
84
|
end
|
@@ -109,5 +109,10 @@ module IO::Endpoint
|
|
109
109
|
|
110
110
|
IO::Endpoint.public_send(uri.scheme, uri.host, uri.port, **options)
|
111
111
|
end
|
112
|
+
|
113
|
+
# The default wrapper to use for binding, connecting, and accepting connections.
|
114
|
+
def wrapper
|
115
|
+
@options[:wrapper] || Wrapper.default
|
116
|
+
end
|
112
117
|
end
|
113
118
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2023, by Samuel Williams.
|
4
|
+
# Copyright, 2023-2025, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "address_endpoint"
|
7
7
|
|
8
8
|
module IO::Endpoint
|
9
9
|
class HostEndpoint < Generic
|
@@ -38,7 +38,7 @@ module IO::Endpoint
|
|
38
38
|
# @yield [Socket] the socket which is being connected, may be invoked more than once
|
39
39
|
# @return [Socket] the connected socket
|
40
40
|
# @raise if no connection could complete successfully
|
41
|
-
def connect(wrapper =
|
41
|
+
def connect(wrapper = self.wrapper, &block)
|
42
42
|
last_error = nil
|
43
43
|
|
44
44
|
Addrinfo.foreach(*@specification) do |address|
|
@@ -63,7 +63,7 @@ module IO::Endpoint
|
|
63
63
|
# Invokes the given block for every address which can be bound to.
|
64
64
|
# @yield [Socket] the bound socket
|
65
65
|
# @return [Array<Socket>] an array of bound sockets
|
66
|
-
def bind(wrapper =
|
66
|
+
def bind(wrapper = self.wrapper, &block)
|
67
67
|
Addrinfo.foreach(*@specification).map do |address|
|
68
68
|
wrapper.bind(address, **@options, &block)
|
69
69
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2023, by Samuel Williams.
|
4
|
+
# Copyright, 2023-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "generic"
|
7
7
|
|
8
8
|
module IO::Endpoint
|
9
9
|
# This class doesn't exert ownership over the specified socket, wraps a native ::IO.
|
@@ -3,10 +3,10 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2023-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
6
|
+
require_relative "host_endpoint"
|
7
|
+
require_relative "generic"
|
8
8
|
|
9
|
-
require
|
9
|
+
require "openssl"
|
10
10
|
|
11
11
|
module OpenSSL
|
12
12
|
module SSL
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2023, by Samuel Williams.
|
4
|
+
# Copyright, 2023-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "address_endpoint"
|
7
7
|
|
8
8
|
module IO::Endpoint
|
9
9
|
# This class doesn't exert ownership over the specified unix socket and ensures exclusive access by using `flock` where possible.
|
data/lib/io/endpoint/version.rb
CHANGED
data/lib/io/endpoint/wrapper.rb
CHANGED
@@ -1,14 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2023-
|
4
|
+
# Copyright, 2023-2025, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
6
|
+
require "socket"
|
7
7
|
|
8
8
|
module IO::Endpoint
|
9
9
|
class Wrapper
|
10
10
|
include ::Socket::Constants
|
11
11
|
|
12
|
+
if Fiber.respond_to?(:scheduler)
|
13
|
+
def schedule(&block)
|
14
|
+
if Fiber.scheduler
|
15
|
+
Fiber.schedule(&block)
|
16
|
+
else
|
17
|
+
Thread.new(&block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
else
|
21
|
+
def schedule(&block)
|
22
|
+
Thread.new(&block)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Legacy method for compatibility with older code.
|
27
|
+
def async(&block)
|
28
|
+
schedule(&block)
|
29
|
+
end
|
30
|
+
|
12
31
|
def set_timeout(io, timeout)
|
13
32
|
if io.respond_to?(:timeout=)
|
14
33
|
io.timeout = timeout
|
@@ -30,8 +49,13 @@ module IO::Endpoint
|
|
30
49
|
# It may not be supported by the protocol (e.g. UDP). ¯\_(ツ)_/¯
|
31
50
|
end
|
32
51
|
|
33
|
-
|
34
|
-
|
52
|
+
# Connect a socket to a remote address.
|
53
|
+
# This is an extension point for subclasses to provide additional functionality.
|
54
|
+
#
|
55
|
+
# @parameter socket [Socket] The socket to connect.
|
56
|
+
# @parameter remote_address [Address] The remote address to connect to.
|
57
|
+
def socket_connect(socket, remote_address)
|
58
|
+
socket.connect(remote_address.to_sockaddr)
|
35
59
|
end
|
36
60
|
|
37
61
|
# Establish a connection to a given `remote_address`.
|
@@ -72,7 +96,7 @@ module IO::Endpoint
|
|
72
96
|
end
|
73
97
|
|
74
98
|
begin
|
75
|
-
socket
|
99
|
+
socket_connect(socket, remote_address)
|
76
100
|
rescue Exception
|
77
101
|
socket.close
|
78
102
|
raise
|
@@ -142,7 +166,7 @@ module IO::Endpoint
|
|
142
166
|
|
143
167
|
return socket unless block_given?
|
144
168
|
|
145
|
-
|
169
|
+
schedule do
|
146
170
|
begin
|
147
171
|
yield socket
|
148
172
|
ensure
|
@@ -151,11 +175,21 @@ module IO::Endpoint
|
|
151
175
|
end
|
152
176
|
end
|
153
177
|
|
178
|
+
# Accept a connection from a bound socket.
|
179
|
+
# This is an extension point for subclasses to provide additional functionality.
|
180
|
+
#
|
181
|
+
# @parameter server [Socket] The bound server socket.
|
182
|
+
# @returns [Tuple(Socket, Address)] The connected socket and the remote address.
|
183
|
+
def socket_accept(server)
|
184
|
+
server.accept
|
185
|
+
end
|
186
|
+
|
154
187
|
# Bind to a local address and accept connections in a loop.
|
155
188
|
def accept(server, timeout: nil, linger: nil, **options, &block)
|
156
189
|
# Ensure we use a `loop do ... end` so that state is not leaked between iterations:
|
190
|
+
|
157
191
|
loop do
|
158
|
-
socket, address = server
|
192
|
+
socket, address = socket_accept(server)
|
159
193
|
|
160
194
|
if linger
|
161
195
|
socket.setsockopt(SOL_SOCKET, SO_LINGER, 1)
|
@@ -165,7 +199,7 @@ module IO::Endpoint
|
|
165
199
|
set_timeout(socket, timeout)
|
166
200
|
end
|
167
201
|
|
168
|
-
|
202
|
+
schedule do
|
169
203
|
# Some sockets, notably SSL sockets, need application level negotiation before they are ready:
|
170
204
|
if socket.respond_to?(:start)
|
171
205
|
begin
|
@@ -183,31 +217,11 @@ module IO::Endpoint
|
|
183
217
|
end
|
184
218
|
end
|
185
219
|
end
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
def
|
190
|
-
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
class FiberWrapper < Wrapper
|
195
|
-
def async(&block)
|
196
|
-
::Fiber.schedule(&block)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
if Fiber.respond_to?(:scheduler)
|
201
|
-
def Wrapper.default
|
202
|
-
if Fiber.scheduler
|
203
|
-
FiberWrapper.new
|
204
|
-
else
|
205
|
-
ThreadWrapper.new
|
206
|
-
end
|
207
|
-
end
|
208
|
-
else
|
209
|
-
def Wrapper.default
|
210
|
-
ThreadWrapper.new
|
220
|
+
|
221
|
+
DEFAULT = new
|
222
|
+
|
223
|
+
def self.default
|
224
|
+
DEFAULT
|
211
225
|
end
|
212
226
|
end
|
213
227
|
end
|
data/license.md
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-endpoint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain:
|
11
10
|
- |
|
@@ -37,10 +36,8 @@ cert_chain:
|
|
37
36
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
38
37
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
39
38
|
-----END CERTIFICATE-----
|
40
|
-
date:
|
39
|
+
date: 2025-02-13 00:00:00.000000000 Z
|
41
40
|
dependencies: []
|
42
|
-
description:
|
43
|
-
email:
|
44
41
|
executables: []
|
45
42
|
extensions: []
|
46
43
|
extra_rdoc_files: []
|
@@ -66,7 +63,6 @@ licenses:
|
|
66
63
|
metadata:
|
67
64
|
documentation_uri: https://socketry.github.io/io-endpoint
|
68
65
|
source_code_uri: https://github.com/socketry/io-endpoint.git
|
69
|
-
post_install_message:
|
70
66
|
rdoc_options: []
|
71
67
|
require_paths:
|
72
68
|
- lib
|
@@ -81,8 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
77
|
- !ruby/object:Gem::Version
|
82
78
|
version: '0'
|
83
79
|
requirements: []
|
84
|
-
rubygems_version: 3.
|
85
|
-
signing_key:
|
80
|
+
rubygems_version: 3.6.2
|
86
81
|
specification_version: 4
|
87
82
|
summary: Provides a separation of concerns interface for IO endpoints.
|
88
83
|
test_files: []
|
metadata.gz.sig
CHANGED
@@ -1,2 +1,4 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
m�����h9tq]G�d���o}�W L,P��\d���N@��x\"���gx":M8 �����zar)��:�݊�˕�Hh{�B�Z[�].l���*�5�&�s4bA���c�����=�1�m����x�a�z2�l%n��P�ջOčpmL���6����
|
2
|
+
@@���Nۏ��ܐ�Q}r���
|
3
|
+
�幊c��@ �\�G6�����ޢ
|
4
|
+
�H�Y�ߍV��(�֑����R�R�4坼�
|