io-endpoint 0.16.0 → 0.17.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85b2a321334cd16a75da466ebff7b9f380410788f173936e9bffd5482599e2ad
4
- data.tar.gz: f207fe739fe89220f59037ec54b1020795509598d4f0deb7a9caaf2cb36e8ea5
3
+ metadata.gz: 99b21a2454e10904ebbf717bf4c1f5dcc337db1a50c88cefea5ef25116759ef2
4
+ data.tar.gz: 4f789220815ddc651cf8397697e30924660c231bebcdb2375f14eac1785fed39
5
5
  SHA512:
6
- metadata.gz: 7154bdc644a2e8f2689567b9804d4019c263f07dd28f44ec98084ed4c3459ea1521724dcf0d4b90d2be9928a9eb4bbcb58895e18e10d461109f91dbdc6cb45ea
7
- data.tar.gz: d8f01abe1ee5d1c93184505f03c2ec4226b6b4eed20754d413b8dcdfa5d5e339d3169069a420fac31b26eca2e157548ad7479e51f8457a14c8f3db5d1efe9e78
6
+ metadata.gz: 4c1720d279b749cd199455eb42ef4fe023a62287100230734d989b6dd8a944b8585c5f5565fa5899aa30b8563ae6350e938632e0c7b2a0b816d80f7273ddf81a
7
+ data.tar.gz: 06baff00190678e64cd396e6ac90e4f6a3e136295fabbaa92b6e7ab7d3894ab9345e084430745d6e0ba0633af7ed240a8478009fafc12134d3886aad4c642e05
checksums.yaml.gz.sig CHANGED
Binary file
data/context/index.yaml CHANGED
@@ -10,3 +10,8 @@ files:
10
10
  title: Getting Started
11
11
  description: This guide explains how to get started with `io-endpoint`, a library
12
12
  that provides a separation of concerns interface for network I/O endpoints.
13
+ - path: named-endpoints.md
14
+ title: Named Endpoints
15
+ description: This guide explains how to use `IO::Endpoint::NamedEndpoints` to manage
16
+ multiple endpoints by name, enabling scenarios like running the same application
17
+ on different protocols or ports.
@@ -0,0 +1,140 @@
1
+ # Named Endpoints
2
+
3
+ This guide explains how to use `IO::Endpoint::NamedEndpoints` to manage multiple endpoints by name, enabling scenarios like running the same application on different protocols or ports.
4
+
5
+ ## Overview
6
+
7
+ `NamedEndpoints` is a collection of endpoints that can be accessed by symbolic names. Unlike {ruby IO::Endpoint::CompositeEndpoint}, which treats endpoints as an ordered list for failover, `NamedEndpoints` allows you to:
8
+
9
+ - **Access endpoints by name**: Use symbolic keys like `:http1` or `:http2` instead of array indices.
10
+ - **Run multiple configurations**: Serve the same application on different protocols, ports, or transports simultaneously.
11
+ - **Iterate over endpoints**: Process all endpoints while maintaining their names for configuration lookup.
12
+
13
+ ## When to Use NamedEndpoints
14
+
15
+ Use `NamedEndpoints` when you need to:
16
+
17
+ - Run the same server application on multiple endpoints with different configurations (e.g., HTTP/1 and HTTP/2).
18
+ - Access endpoints by symbolic names rather than position.
19
+ - Bind multiple endpoints and create servers for each one.
20
+ - Manage a collection of endpoints where each has a specific role or configuration.
21
+
22
+ If you need failover behavior (trying endpoints in order until one succeeds), use {ruby IO::Endpoint::CompositeEndpoint} instead.
23
+
24
+ ## Creating Named Endpoints
25
+
26
+ ### Using the Constructor
27
+
28
+ Create a `NamedEndpoints` instance by passing a hash of endpoints:
29
+
30
+ ```ruby
31
+ require "io/endpoint"
32
+
33
+ http1_endpoint = IO::Endpoint.tcp("localhost", 8080)
34
+ http2_endpoint = IO::Endpoint.tcp("localhost", 8090)
35
+
36
+ named = IO::Endpoint::NamedEndpoints.new(
37
+ http1: http1_endpoint,
38
+ http2: http2_endpoint
39
+ )
40
+ ```
41
+
42
+ ### Using the Factory Method
43
+
44
+ The `IO::Endpoint.named` factory method provides a convenient way to create named endpoints:
45
+
46
+ ```ruby
47
+ require "io/endpoint"
48
+
49
+ named = IO::Endpoint.named(
50
+ http1: IO::Endpoint.tcp("localhost", 8080),
51
+ http2: IO::Endpoint.tcp("localhost", 8090),
52
+ https: IO::Endpoint.ssl("localhost", 8443)
53
+ )
54
+ ```
55
+
56
+ ## Accessing Endpoints
57
+
58
+ Access endpoints by their names using the `[]` operator:
59
+
60
+ ```ruby
61
+ named = IO::Endpoint.named(
62
+ http1: IO::Endpoint.tcp("localhost", 8080),
63
+ http2: IO::Endpoint.tcp("localhost", 8090)
64
+ )
65
+
66
+ # Access by name
67
+ http1 = named[:http1]
68
+ http2 = named[:http2]
69
+
70
+ # Returns nil if not found
71
+ missing = named[:nonexistent] # => nil
72
+ ```
73
+
74
+ ## Iterating Over Endpoints
75
+
76
+ ### Using `each`
77
+
78
+ The `each` method yields both the name and endpoint:
79
+
80
+ ```ruby
81
+ named = IO::Endpoint.named(
82
+ http1: IO::Endpoint.tcp("localhost", 8080),
83
+ http2: IO::Endpoint.tcp("localhost", 8090)
84
+ )
85
+
86
+ named.each do |name, endpoint|
87
+ puts "Endpoint #{name} is bound to #{endpoint}"
88
+ end
89
+ ```
90
+
91
+ To map over endpoint values, use `endpoints.values.map`:
92
+
93
+ ```ruby
94
+ protocols = named.endpoints.values.map do |endpoint|
95
+ endpoint.protocol.to_s
96
+ end
97
+
98
+ # => ["HTTP1", "HTTP2"]
99
+ ```
100
+
101
+ ## Binding Endpoints
102
+
103
+ To bind endpoints, iterate over the collection and bind each endpoint individually, or use the `bound` method to create a new collection with all endpoints bound.
104
+
105
+ The `bound` method creates a new `NamedEndpoints` instance where all endpoints are bound:
106
+
107
+ ```ruby
108
+ named = IO::Endpoint.named(
109
+ http1: IO::Endpoint.tcp("localhost", 8080),
110
+ http2: IO::Endpoint.tcp("localhost", 8090)
111
+ )
112
+
113
+ bound_named = named.bound(reuse_address: true)
114
+
115
+ # All endpoints are now bound
116
+ bound_named.each do |name, bound_endpoint|
117
+ server = bound_endpoint.sockets.first
118
+ server.listen(10)
119
+ end
120
+ ```
121
+
122
+ ## Connecting to Endpoints
123
+
124
+ To connect to a specific endpoint, access it by name and call `connect` on that endpoint:
125
+
126
+ ```ruby
127
+ named = IO::Endpoint.named(
128
+ primary: IO::Endpoint.tcp("server1.example.com", 80),
129
+ secondary: IO::Endpoint.tcp("server2.example.com", 80)
130
+ )
131
+
132
+ # Connect to a specific endpoint by name
133
+ named[:primary].connect do |socket|
134
+ socket.write("GET / HTTP/1.1\r\n\r\n")
135
+ response = socket.read
136
+ puts response
137
+ end
138
+ ```
139
+
140
+ If you need failover behavior (trying endpoints in order until one succeeds), use {ruby IO::Endpoint::CompositeEndpoint} instead.
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2026, by Samuel Williams.
5
+
6
+ require_relative "generic"
7
+
8
+ module IO::Endpoint
9
+ # A named endpoints collection is a hash of endpoints that can be accessed by name.
10
+ #
11
+ # Unlike {CompositeEndpoint}, which treats endpoints as an ordered list for failover, `NamedEndpoints` allows you to access endpoints by symbolic names, making it useful for scenarios where you need to run the same application on multiple endpoints with different configurations (e.g., HTTP/1 and HTTP/2 on different ports).
12
+ class NamedEndpoints
13
+ # Initialize a new named endpoints collection.
14
+ # @parameter endpoints [Hash(Symbol, Generic)] A hash mapping endpoint names to endpoint instances.
15
+ def initialize(endpoints)
16
+ @endpoints = endpoints
17
+ end
18
+
19
+ # @attribute [Hash(Symbol, Generic)] The endpoints hash mapping names to endpoint instances.
20
+ attr :endpoints
21
+
22
+ # Access an endpoint by its name.
23
+ # @parameter key [Symbol] The name of the endpoint to access.
24
+ # @returns [Generic, nil] The endpoint with the given name, or nil if not found.
25
+ def [] key
26
+ @endpoints[key]
27
+ end
28
+
29
+ # Enumerate all endpoints with their names.
30
+ # @yields {|name, endpoint| ...} For each endpoint, yields the name and endpoint.
31
+ # @parameter name [Symbol] The name of the endpoint.
32
+ # @parameter endpoint [Generic] The endpoint.
33
+ def each(&block)
34
+ @endpoints.each(&block)
35
+ end
36
+
37
+ # Create a new named endpoints instance with all endpoints bound.
38
+ # @parameter options [Hash] Options to pass to each endpoint's bound method.
39
+ # @returns [NamedEndpoints] A new instance with bound endpoints.
40
+ def bound(**options)
41
+ self.class.new(
42
+ @endpoints.transform_values{|endpoint| endpoint.bound(**options)}
43
+ )
44
+ end
45
+
46
+ # Create a new named endpoints instance with all endpoints connected.
47
+ # @parameter options [Hash] Options to pass to each endpoint's connected method.
48
+ # @returns [NamedEndpoints] A new instance with connected endpoints.
49
+ def connected(**options)
50
+ self.class.new(
51
+ @endpoints.transform_values{|endpoint| endpoint.connected(**options)}
52
+ )
53
+ end
54
+
55
+ # Close all endpoints in the collection.
56
+ # Calls `close` on each endpoint value.
57
+ # @returns [void]
58
+ def close
59
+ @endpoints.each_value(&:close)
60
+ end
61
+ end
62
+
63
+ # Create a named endpoints collection from keyword arguments.
64
+ # @parameter endpoints [Hash(Symbol, Generic)] Named endpoints as keyword arguments.
65
+ # @returns [NamedEndpoints] A new named endpoints instance.
66
+ # @example Create a named endpoints collection
67
+ # endpoints = IO::Endpoint.named(
68
+ # http1: IO::Endpoint.tcp("localhost", 8080),
69
+ # http2: IO::Endpoint.tcp("localhost", 8090)
70
+ # )
71
+ def self.named(**endpoints)
72
+ NamedEndpoints.new(endpoints)
73
+ end
74
+ end
@@ -7,6 +7,6 @@
7
7
  class IO
8
8
  # @namespace
9
9
  module Endpoint
10
- VERSION = "0.16.0"
10
+ VERSION = "0.17.0"
11
11
  end
12
12
  end
data/lib/io/endpoint.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2023-2024, by Samuel Williams.
4
+ # Copyright, 2023-2025, by Samuel Williams.
5
5
 
6
6
  require_relative "endpoint/version"
7
7
  require_relative "endpoint/generic"
data/license.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright, 2023-2025, by Samuel Williams.
3
+ Copyright, 2023-2026, by Samuel Williams.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -10,6 +10,58 @@ Please see the [project documentation](https://socketry.github.io/io-endpoint) f
10
10
 
11
11
  - [Getting Started](https://socketry.github.io/io-endpointguides/getting-started/index) - This guide explains how to get started with `io-endpoint`, a library that provides a separation of concerns interface for network I/O endpoints.
12
12
 
13
+ - [Named Endpoints](https://socketry.github.io/io-endpointguides/named-endpoints/index) - This guide explains how to use `IO::Endpoint::NamedEndpoints` to manage multiple endpoints by name, enabling scenarios like running the same application on different protocols or ports.
14
+
15
+ ## Releases
16
+
17
+ Please see the [project releases](https://socketry.github.io/io-endpointreleases/index) for all releases.
18
+
19
+ ### v0.17.0
20
+
21
+ - Added `IO::Endpoint::NamedEndpoints` for accessing endpoints by symbolic names, useful for running applications on multiple endpoints with different configurations.
22
+
23
+ ### v0.16.0
24
+
25
+ - Improved error handling in `#connect` for more robust connection handling.
26
+ - Added getting started guide and improved documentation coverage.
27
+
28
+ ### v0.15.2
29
+
30
+ - Fixed `UNIXEndpoint#bind` to pass all arguments through to super.
31
+
32
+ ### v0.15.1
33
+
34
+ - Added `async-dns` to externals and restored removed method.
35
+
36
+ ### v0.15.0
37
+
38
+ - Allow wrapper to be customized using endpoint `options[:wrapper]`.
39
+ - Expose wrapper extension points for `connect` and `accept`.
40
+
41
+ ### v0.14.0
42
+
43
+ - Uniform `#to_s` and `#inspect` implementations across all endpoints.
44
+
45
+ ### v0.13.1
46
+
47
+ - Fixed state leak between iterations of the accept loop.
48
+
49
+ ### v0.13.0
50
+
51
+ - Propagate options assigned to composite endpoint to nested endpoints.
52
+
53
+ ### v0.12.0
54
+
55
+ - Expose `size` and internal endpoints for composite endpoint.
56
+
57
+ ### v0.10.3
58
+
59
+ - Fixed `SSLServer#accept` failures causing accept loop to exit. (\#10)
60
+
61
+ ## See Also
62
+
63
+ - [async-io](https://github.com/socketry/async-io) — Where this implementation originally came from.
64
+
13
65
  ## Contributing
14
66
 
15
67
  We welcome contributions to this project.
@@ -27,7 +79,3 @@ In order to protect users of this project, we require all contributors to comply
27
79
  ### Community Guidelines
28
80
 
29
81
  This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
30
-
31
- ## See Also
32
-
33
- - [async-io](https://github.com/socketry/async-io) — Where this implementation originally came from.
data/releases.md ADDED
@@ -0,0 +1,107 @@
1
+ # Releases
2
+
3
+ ## v0.17.0
4
+
5
+ - Added `IO::Endpoint::NamedEndpoints` for accessing endpoints by symbolic names, useful for running applications on multiple endpoints with different configurations.
6
+
7
+ ## v0.16.0
8
+
9
+ - Improved error handling in `#connect` for more robust connection handling.
10
+ - Added getting started guide and improved documentation coverage.
11
+
12
+ ## v0.15.2
13
+
14
+ - Fixed `UNIXEndpoint#bind` to pass all arguments through to super.
15
+
16
+ ## v0.15.1
17
+
18
+ - Added `async-dns` to externals and restored removed method.
19
+
20
+ ## v0.15.0
21
+
22
+ - Allow wrapper to be customized using endpoint `options[:wrapper]`.
23
+ - Expose wrapper extension points for `connect` and `accept`.
24
+
25
+ ## v0.14.0
26
+
27
+ - Uniform `#to_s` and `#inspect` implementations across all endpoints.
28
+
29
+ ## v0.13.1
30
+
31
+ - Fixed state leak between iterations of the accept loop.
32
+
33
+ ## v0.13.0
34
+
35
+ - Propagate options assigned to composite endpoint to nested endpoints.
36
+
37
+ ## v0.12.0
38
+
39
+ - Expose `size` and internal endpoints for composite endpoint.
40
+
41
+ ## v0.10.3
42
+
43
+ - Fixed `SSLServer#accept` failures causing accept loop to exit. (\#10)
44
+
45
+ ## v0.10.2
46
+
47
+ - Centralized usage of `listen` to wrapper.
48
+
49
+ ## v0.10.1
50
+
51
+ - Ensure `listen` is called.
52
+
53
+ ## v0.10.0
54
+
55
+ - Don't hardcode timeout support - detect at run-time.
56
+
57
+ ## v0.9.0
58
+
59
+ - Correctly set `sync_close`. (\#7)
60
+
61
+ ## v0.8.1
62
+
63
+ - Remove broken `require_relative 'readable'`.
64
+
65
+ ## v0.8.0
66
+
67
+ - Removed `IO#readable?` dependency in favor of `io-stream` gem.
68
+
69
+ ## v0.7.2
70
+
71
+ - Added missing `SSLSocket#remote_address`.
72
+
73
+ ## v0.7.1
74
+
75
+ - Improved shims for `IO#readable?`.
76
+
77
+ ## v0.7.0
78
+
79
+ - Fixed shim for `OpenSSL::SSL::SSLSocket#local_address`.
80
+ - Added shim for `IO#readable?`.
81
+
82
+ ## v0.6.0
83
+
84
+ - Allow `Wrapper#accept` to ignore unknown options.
85
+
86
+ ## v0.5.0
87
+
88
+ - Fixed the OpenSSL shims. (\#5)
89
+ - Simplified implementation and separated connected/bound options. (\#4)
90
+
91
+ ## v0.4.0
92
+
93
+ - Improved compatibility with `async-http`/`async-io`. (\#3)
94
+
95
+ ## v0.3.0
96
+
97
+ - Fixed OpenSSL integration. (\#2)
98
+
99
+ ## v0.2.0
100
+
101
+ - Added option `buffered:` for controlling `TCP_NODELAY`.
102
+
103
+ ## v0.1.0
104
+
105
+ - Initial implementation extracted from `async-io`.
106
+ - Added support for thread and fiber wrappers.
107
+ - Support Ruby 2.7+ with optional `set_timeout`.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-endpoint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -44,6 +44,7 @@ extra_rdoc_files: []
44
44
  files:
45
45
  - context/getting-started.md
46
46
  - context/index.yaml
47
+ - context/named-endpoints.md
47
48
  - lib/io/endpoint.rb
48
49
  - lib/io/endpoint/address_endpoint.rb
49
50
  - lib/io/endpoint/bound_endpoint.rb
@@ -51,6 +52,7 @@ files:
51
52
  - lib/io/endpoint/connected_endpoint.rb
52
53
  - lib/io/endpoint/generic.rb
53
54
  - lib/io/endpoint/host_endpoint.rb
55
+ - lib/io/endpoint/named_endpoints.rb
54
56
  - lib/io/endpoint/shared_endpoint.rb
55
57
  - lib/io/endpoint/socket_endpoint.rb
56
58
  - lib/io/endpoint/ssl_endpoint.rb
@@ -59,6 +61,7 @@ files:
59
61
  - lib/io/endpoint/wrapper.rb
60
62
  - license.md
61
63
  - readme.md
64
+ - releases.md
62
65
  homepage: https://github.com/socketry/io-endpoint
63
66
  licenses:
64
67
  - MIT
metadata.gz.sig CHANGED
Binary file