hick-compio 0.2.0

compio-native async mDNS driver (responder + querier + DNS-SD discovery), thread-per-core.
Documentation

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

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

Feature Description
tracing Forward structured tracing spans/events from the driver and mdns-proto.
stats Enable atomic counters; read a snapshot via endpoint.stats().
metrics Bridge 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.