Skip to main content

Crate base_endpoint

Crate base_endpoint 

Source
Expand description

Reusable descriptions of how to connect and bind, inspired by Ruby’s IO::Endpoint. Application code depends on endpoint contracts; endpoint implementations handle resolution, socket creation and establishment through explicit base-scheduler capabilities. The API is experimental.

ConnectEndpoint<S> returns an associated Connection; BindEndpoint<S> returns a collection of associated Listener values. Implementations choose these representations, so consumers can abstract over establishment without hard-coding TCP or a particular runtime. The traits are separate so a connecting consumer does not need binding capabilities. The built-in TCP implementations return the scheduler’s native socket type for use with its existing accept and I/O APIs.

use base_endpoint::{BindEndpoint, BindOptions, ConnectEndpoint, HostEndpoint};
use base_scheduler::{Cancellation, SocketAccept, SocketClose, SocketLocalAddress};
use base_scheduler_native::NativeScheduler;

let scheduler = NativeScheduler::new()?;
scheduler.block_on(async {
    let cancellation = Cancellation::never();

    let listeners = HostEndpoint::new("127.0.0.1", 0)
        .bind(&scheduler, BindOptions::default(), &cancellation).await?;
    let port = scheduler.socket_local_address(&listeners[0])?.port();
    let client = HostEndpoint::new("127.0.0.1", port)
        .connect(&scheduler, &cancellation).await?;
    let (accepted, _peer) = scheduler.socket_accept(&listeners[0], &cancellation).await?;

    // Use scheduler-bound stream readers/writers here. Retire and drop them
    // before closing their sockets.
    scheduler.socket_close(client).await?;
    scheduler.socket_close(accepted).await?;
    for listener in listeners {
        scheduler.socket_close(listener).await?;
    }
    scheduler.shutdown().await;
    Ok::<(), base_scheduler::OperationError>(())
})?;

A consumer can work entirely through the connection contract:

use base_endpoint::ConnectEndpoint;
use base_scheduler::{Cancellation, OperationResult};

async fn establish<S: Sync, E: ConnectEndpoint<S>>(
    scheduler: &S,
    endpoint: &E,
    cancellation: &Cancellation,
) -> OperationResult<E::Connection> {
    endpoint.connect(scheduler, cancellation).await
}

§TCP endpoints

AddressEndpoint::new(socket_address) describes a numeric TCP address and needs no resolver. HostEndpoint::new(hostname, port) resolves afresh for each operation. HostEndpoint::wildcard(port) binds local interfaces and resolves loopback addresses when connecting. with_domain(SocketDomain::Ipv4) or Ipv6 restricts resolution. resolve exposes numeric endpoints when callers need to inspect candidates.

§Composition and fallback

CompositeEndpoint::new(vec![...]) connects to the first successful child, preserving order and returning the last failure if all attempts fail. Bind creates all child listeners; a later failure closes earlier listeners before returning. Host endpoints use the same policy for resolved addresses. Cancellation stops fallback, and empty candidate sets fail with AddrNotAvailable. Binding composition currently requires listeners that the supplied scheduler can close; connection composition supports arbitrary connection representations.

§Binding

Binding includes listening with the requested backlog. All candidates must bind successfully; there is no best-effort family fallback. Resolver ordering and duplicates are preserved. Wildcard IPv4/IPv6 overlap follows the operating system’s dual-stack policy and may cause binding to fail; select one family when needed. With port zero each listener receives its own OS-selected port, available through SocketLocalAddress.

§Ownership and cancellation

Endpoints retain no scheduler and spawn no tasks. Pass cancellation explicitly and await the operation to finish rollback before scheduler shutdown. Failed connection attempts close their sockets before fallback; failed binds close every socket created by that operation. Cleanup is awaited without the cancelled signal, and the primary establishment error is retained if closing also reports an error. Dropping a pending future provides ordinary destruction only, without an asynchronous join. Successful sockets and their cleanup belong to the caller.

§Scope

The first concrete transport covers TCP over IPv4/IPv6. TCP uses OS option defaults. UNIX sockets, UDP, URI parsing, named endpoints, socket-option policies, local source binding, Happy Eyeballs and built-in timeouts are not provided. The scheduler currently exposes only IP socket creation/address operations, so UNIX sockets need a scheduler extension. No concrete runtime is a production dependency; rustls is optional.

The tls module composes these endpoints with provider-neutral TLS, including an optional rustls provider. The stream module describes plaintext byte I/O for established transports.

Modules§

stream
Plaintext byte-stream capabilities for established transports.
tls
Provider-neutral TLS handshakes, stream I/O and endpoint composition. The optional rustls feature supplies a concrete provider in tls::rustls. Applications select trust stores and credentials through provider configuration.

Structs§

AddressEndpoint
A TCP endpoint at one numeric IPv4 or IPv6 address. Construction performs no I/O, and operations require no resolver capability.
BindOptions
Listening configuration passed to a binding operation.
CompositeEndpoint
An ordered collection of endpoints of one type. Connecting tries children in order until one succeeds. Binding creates every child’s listeners and rolls them all back if a later child fails. Empty collections fail with AddrNotAvailable.
HostEndpoint
A TCP endpoint resolved afresh for each connect or bind. Connection attempts follow resolver order; binding creates a listener for every resolved address. There is no cache or background resolver task.

Traits§

BindEndpoint
A reusable description of how to create listeners. Consumers need not know how addresses are resolved or sockets are created. Binding may produce multiple listeners, for example one per IP family.
ConnectEndpoint
A reusable description of how to establish a connection. Consumers depend on this contract rather than DNS, addresses, or socket construction. S supplies explicit execution capabilities; the endpoint retains no scheduler and spawns no tasks.