Skip to main content

Crate socketry

Crate socketry 

Source
Expand description

Foundational concurrency APIs for Socketry.

§socketry

Foundational concurrency APIs for Rust projects in the Socketry ecosystem.

The socketry package re-exports socketry-executor: owned asynchronous tasks, explicit child barriers, and a futures executor with multiple workers and work stealing. Tasks use ordinary future polling and have no private coroutine stacks.

§Usage

[dependencies]
socketry = "0.1"
use socketry::{Scheduler, yield_now};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let scheduler = Scheduler::with_workers(4)?;
    let task = scheduler.spawn(async {
        yield_now().await;
        42
    })?;

    let answer = scheduler.block_on(task)?;
    assert_eq!(answer, 42);
    Ok(())
}

Workers start when the scheduler is constructed. spawn accepts Send + 'static futures and returns an awaitable result handle. Dropping that handle leaves the task owned by its scheduler or barrier. Dropping the scheduler requests cancellation and joins workers when called outside a worker.

Use scheduler.barrier() to own children explicitly. Both schedulers and barriers implement Spawn. barrier.wait().await waits for completion; barrier.stop().await closes the barrier, cancels children, and waits for their synchronous destructors. Dropping a barrier requests cancellation without waiting. Observe individual results and panics through task handles.

Scheduler::current() and Task::current() provide contextual lookup while tasks run. Use .await to suspend; synchronous blocking calls occupy a worker.

See the executor package for scheduling, ownership, cancellation and allocation details. An executable example is:

cargo run --package socketry-executor --example work_stealing

§Portable I/O and runtime selection

Generic code can accept Network, FileIo, Clock, and Spawn capabilities. Socketry and the optional Tokio adapter implement these contracts with concrete future and resource types. Import the traits to call their methods.

Cargo configurationImplementation
Default (native)Socketry tasks; epoll, kqueue or Windows IOCP/AFD socket readiness through async-io.
features = ["io-uring"] on LinuxNative completion reads/writes through an io_uring selector.
features = ["tokio"]Also expose socketry::scheduler::tokio::Scheduler, adapting an existing Tokio runtime.
default-features = false, features = ["tokio"]Tokio adapter without Socketry’s native I/O dependencies.
default-features = falseTask executor and portable contracts, without I/O implementations.

Socket registrations persist across operations and worker migration. Reads and writes take a reusable owned Vec<u8> and return (io::Result<usize>, Vec<u8>). Reads fill the buffer’s existing length; allocate it with vec![0; capacity]. Operations may transfer fewer bytes than requested. Dropping a future can abandon an operation that has already consumed or transmitted bytes.

Run the same TCP exchange with either runtime:

cargo run -p socketry-executor --example portable_io
cargo run -p socketry-executor --example portable_io --no-default-features --features tokio
# Linux native completion:
cargo run -p socketry-executor --example portable_io --features io-uring

The Tokio adapter needs a live runtime with I/O and time enabled. It preserves explicit task/barrier ownership, and its asynchronous shutdown().await joins task destruction. Passing its handle explicitly selects Tokio; Socketry’s Scheduler::current() continues to identify Socketry execution.

§Current scope

TCP connect/accept/read/write/readiness, positioned file reads/writes, and sleep are implemented. Regular files use blocking pools except for Linux io_uring. Windows socket readiness uses IOCP/AFD; native overlapped file operations are not implemented. Socketry currently uses async-io’s shared readiness reactor and timers; the io-event timer port remains planned in the design guide.

The io_uring selector owns a dedicated thread, retains buffers until terminal completions, and drains cancellation during shutdown. Connection setup and readiness waits still use async-io. Kernel support is probed when the selector is first needed; failures are returned without silently falling back. Operation pooling, registered buffers, UDP, arbitrary descriptor APIs, and a local !Send task executor remain future work.

The former coroutine implementation is preserved on branch coroutine, at commit b520f3d. Its native sources, stack allocation, nested synchronous wait and task transfer are absent from the future executor.

§Releasing

Prepare a release with cargo bake cargo:version:patch (or minor, major, or bump --version X.Y.Z), then run cargo bake cargo:release and open a pull request. After review and merge, GitHub Actions publishes the release when the configured crates-io environment approves it, then creates or updates the matching GitHub Release from releases.md. See the shared Releasing skill for the standard release process.

§Releases

See releases.md for the full release history.

§v0.1.3

  • Use the shared Socketry Project tasks and update agent context setup guidance.

§v0.1.2

  • Use the shared socketry-project Releasing skill for the standard release process and remove references to the duplicate Bake Cargo publishing context.

§v0.1.1

  • Create or update GitHub Releases after successful crates.io publication.
  • Move implementation and design guidance into the package’s public context.
  • Add Bake Agent Context tasks to the repository’s development workspace.

§Contributing

Please open an issue or pull request on GitHub.

§Agent Context

Run cargo bake agent:context:install to install shared context and skills. Read .agents/context/index.md to find relevant guides, follow agents.md if present, and apply skills under .agents/skills/. See the Agent Context guide for guidance on organizing package context and repository-only instructions.

The crate publishes implementation and design guides for its architecture and development.

Re-exports§

pub use socketry_executor as executor;

Modules§

scheduler
Scheduler implementations and their I/O selectors.

Structs§

Barrier
Explicit ownership of child tasks running on a scheduler.
Scheduler
A futures executor with worker queues, remote inboxes and idle work stealing.
SchedulerHandle
A clonable, thread-safe reference for submitting work to a scheduler. Handles do not keep worker threads running after the owning Scheduler closes.
Task
A thread-safe task reference. Holding it does not prevent task cancellation.
TaskHandle
An awaitable result of an owned task.

Enums§

Interest
A socket readiness condition. Readiness can be spurious; retry nonblocking operations and wait again when they return WouldBlock.
SpawnError
A task could not be registered with its owner.
TaskError
A task ended without producing its normal output.

Traits§

Clock
A runtime’s monotonic sleep facility.
FileIo
Positioned file operations. A regular file does not support a universal readiness fallback, so implementations use native completion or a blocking pool. Use ordinary files opened without append mode, not pipes. Offsets must fit in i64. The Unix implementation leaves the shared cursor unchanged; the Windows blocking fallback updates it, as std’s seek_read/seek_write do.
Network
Portable socket operations, selected through the concrete implementation.
Spawn
The common spawning contract for a scheduler and an explicit child owner.

Functions§

yield_now
Cooperatively reschedule the current future once. Works with any executor implementing the standard future/waker contract.

Type Aliases§

BufferResult
An operation result together with its reusable, owned buffer.