Skip to main content

Crate hick_compio

Crate hick_compio 

Source
Expand description

hick-compio

compio-native async mDNS / DNS-SD — responder, querier, and discovery on a thread-per-core, completion-based runtime.

github LoC Build codecov

docs.rs crates.io crates.io license

§Introduction

hick-compio drives the Sans-I/O core (mdns-proto) over compio, a completion-based (io_uring / IOCP) thread-per-core runtime, using the multicast socket helpers from hick-udp.

For the tokio / smol runtimes, use hick-reactor or the hick facade instead.

§Installation

[dependencies]
hick-compio = "0.1"

§Example

Run inside a compio runtime (the driver is !Send, thread-per-core):

use hick_compio::{
    Endpoint, Name, QueryEvent, QuerySpec, ServerOptions, ServiceRecords, ServiceSpec,
    wire::ResourceType,
};

async fn run() -> Result<(), Box<dyn std::error::Error>> {
    let endpoint = Endpoint::server(ServerOptions::default()).await?;

    // Advertise a service. Keep the handle alive to keep advertising; dropping it
    // withdraws the service (TTL=0 goodbye) and unregisters it.
    let mut records = ServiceRecords::new(
        Name::try_from_str("_http._tcp.local.")?,
        Name::try_from_str("My Device._http._tcp.local.")?,
        Name::try_from_str("my-device.local.")?,
        80,
        120,
    );
    records.add_a([192, 168, 1, 10].into());
    let _service = endpoint.register_service(ServiceSpec::new(records)).await?;

    // Discover services of a type on the local link.
    let mut query = endpoint
        .start_query(QuerySpec::new(
            Name::try_from_str("_ipp._tcp.local.")?,
            ResourceType::Ptr,
        ))
        .await?;
    while let Some(event) = query.next().await {
        match event {
            QueryEvent::Answer(answer) => println!("{answer:?}"),
            QueryEvent::Terminal(_) => break,
        }
    }
    Ok(())
}

§Feature flags

FeatureDescription
tracingForward structured tracing spans/events from the driver and mdns-proto.
statsEnable atomic counters; read a snapshot via endpoint.stats().
metricsBridge counters to the metrics facade (Prometheus/StatsD). Implies stats.

§Observability

Enable features = ["tracing"] to have the driver emit tracing events during socket I/O, service probing, and query state transitions.

Enable features = ["stats"] and call endpoint.stats() to obtain a hick_trace::stats::StatsSnapshot:

let snap = endpoint.stats();
println!("packets_rx={} services_active={}", snap.packets_rx, snap.services_active);

Enable features = ["metrics"] to additionally forward every counter/gauge update to the metrics facade automatically.

§Design

  • !Send throughout: no Arc, no Mutex, no atomics, no MPSC channels.
  • One spawned driver future per endpoint, owning the compio UdpSocket(s) and pumping a select! over two in-flight recv_msgs (v4 + v6), a sleep_until timer, and a LocalNotify.
  • Handles (Query, Service, Lookup) hold Rc<EndpointInner> and borrow shared state directly under short, non-.await borrows.

§The hick family

hick (facade) · mdns-proto (Sans-I/O core) · hick-udp (UDP) · hick-reactor (tokio / smol driver) · hick-compio (this crate) · hick-smoltcp (smoltcp engine) · hick-embassy (embassy driver).

§License

hick-compio is under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE, LICENSE-MIT for details.

Copyright (c) 2025 Al Liu.

Re-exports§

pub use discovery::DEFAULT_MAX_ENTRIES;
pub use discovery::Lookup;
pub use discovery::QueryParam;
pub use discovery::ServiceEntry;
pub use endpoint::Endpoint;
pub use error::CancelError;
pub use error::RegisterError;
pub use error::ServerError;
pub use error::StartQueryError;
pub use options::ServerOptions;
pub use query::Query;
pub use query::QueryEvent;
pub use service::Service;

Modules§

discovery
DNS-SD service discovery — data types and parsing helpers.
endpoint
Caller-side handle for an mDNS endpoint.
error
Public error types surfaced by the async API.
options
Caller-facing construction options for Endpoint.
query
Query handle returned by Endpoint::start_query.
service
Service handle returned by Endpoint::register_service.
wire
mDNS wire format — panic-free parser and encoder. mDNS wire format — panic-free, no_alloc-capable parser and encoder.

Structs§

CollectedAnswer
One collected answer record for a Query.
Name
Owned, canonical DNS name (lowercased on construction).
QueryHandle
Opaque identifier for an in-flight query.
QuerySpec
Spec for starting a query.
ServiceHandle
Opaque identifier for a registered service.
ServiceRecords
Records advertised by a single registered service.
ServiceSpec
Spec for registering a service.

Enums§

QueryUpdate
App-level events emitted by Query::poll().
ServiceUpdate
App-level events emitted by Service::poll().