weida
Lines and stations read off cargo metadata at 5a20f15; every segment is a dependency between two workspace crates. Publication state from crates.io. Pending segments from README.md and docs/status/product-line.svg.
What it is
L0L1L2
It is built in layers. L0 is a stream core: ZeroMQ's idea rebuilt on QUIC, whose primitives are unidirectional and bidirectional streams with exactly the guarantees QUIC gives — ordered bytes within a stream, none across streams, flow control, a transport delivery receipt, and cancellation by reset. L1 is the ZeroMQ/nanomsg pattern family as thin wrappers over L0: Req/Rep, Push/Pull, Pub/Sub, PAIR, SURVEY and BUS — the whole nanomsg set, and none of them adds wire vocabulary. L2 is a RabbitMQ-analog broker, weida-broker: queues at endpoint paths, publisher confirms, and an absolute per-subscription credit. Consumer acknowledgement and redelivery are the slice still to come.
The cursor
A completion is a cursor, not a verdict: a level plus an absolute byte offset, reported on a unidirectional stream of its own that never shares a stream with payload. So a Push producer gets a reliable Accepted without an exchange, a reader learns how far the far end got rather than only whether it finished, and no pattern changes shape to gain any of it.
State
Status: alpha. Published on crates.io: weida, weida-core, weida-protocol, weida-runtime and weida-winpipe at 0.1.0-alpha.1 and 0.1.0-alpha.2, and weida-broker, weida-raft and weida-openbao at 0.1.0-alpha.2. The other seventeen members are not published: weida-py-core, every Python binding and all five protocol libraries with their codecs. Nothing is on PyPI and there are no prebuilt binaries. Wire protocol version 0 is experimental and breaking changes are permitted within 0.x. Phases 0-3 are implemented — the docs, the core model, the native QUIC transport, the in-process, AF_UNIX and named-pipe transports, all six patterns, the raw L0 stream API, peer identity by public-key fingerprint, opt-in per-producer ordering and bounded deduplication, a bounded drain, the cursor back channel, a synchronous facade (weida::blocking), a weida binary and a Python binding (weida-py) — and the first two broker slices with them. Beside weida the repository ships five protocol libraries, none of which has weida in its picture: ZeroMQ (weida-zmtp + weida-zmq + weida-zmq-py), the nanomsg SP protocols (weida-sp + weida-nng + weida-nng-py), MQTT 5 (weida-mqtt-codec + weida-mqtt + weida-mqtt-py), AMQP 1.0 (weida-amqp-codec + weida-amqp + weida-amqp-py) and Core NATS (weida-nats-codec + weida-nats + weida-nats-py), each with a parity document under docs/libraries/ and each measured against a real peer where one exists. weida-zmq is complete against decisions/0013 §4.7's definition of first-class — every socket type of zmq_socket(3) bar ZMQ_STREAM, tcp/ipc/inproc, NULL/PLAIN/CURVE with ZAP, the option table honoured or refused row by row, the monitor and the devices, the zguide's canonical recipes as examples that assert the guide's own claims, and interop against libzmq 4.3.5 and the pure-Rust zeromq crate in both roles (docs/libraries/zmq.md). Its typed proxy and proxy_steerable devices include the canonical ROUTER/DEALER queue, XSUB/XPUB forwarder and PULL/PUSH streamer without involving the weida protocol.
From README.md.
Quick start, without writing a program
$ cargo run -q -p weida --bin weida -- serve --echo 'weida://127.0.0.1:7443/echo'
weida://sha256:22ed30a8…9f25@127.0.0.1:7443/echo$ printf 'hello weida' | cargo run -q -p weida --bin weida -- request 'weida://sha256:22ed30a8…9f25@127.0.0.1:7443/echo'
hello weidaIn a program with no reactor, the same shape is a library call: weida::blocking behind the non-default blocking feature wraps every endpoint, one block_on each, over a reactor it owns — and refuses to be called from inside a Tokio runtime, where blocking a worker would deadlock.
Four verbs: serve (with --echo, --sink or --pub), request, send and sub. The payload is on stdin and stdout and nothing else is, so weida request … | sha256sum means what it looks like; addresses, receipts and topics go to stderr. The address serve printed is the whole client configuration, exactly as in the section below. Every transport works the same way — weida+unix://%2Ftmp%2Fs.sock/echo for a socket, weida+pipe://NAME/echo for a Windows pipe — and the exit code names the error a script can act on: 3 refused, 4 unknown endpoint, 5 no reply, 6 untrusted, 7 connection lost. weida --help lists every option, including sub --framing line|raw|nul|length, because a newline after each payload is readable and is not framing.
Identity in one line
A weida peer is its public key. The server generates an identity and prints an address that names it; the client trusts that address and nothing else:
$ cargo run -p weida --example transform_server -- --bind 127.0.0.1:7443
weida://sha256:22ed30a8…9f25@127.0.0.1:7443/transform
weida://sha256:22ed30a8…9f25@127.0.0.1:7443/echo$ printf 'hello weida' | cargo run -p weida --example transform_client -- 'weida://sha256:22ed30a8…9f25@127.0.0.1:7443/transform'
HELLO WEIDANo certificate file changes hands, no CA exists, and a peer with any other key is refused with Untrusted(sha256:…) naming the key that answered. --identity PATH keeps the server's key across restarts so the address stays stable; --cert-out PATH plus transform_client --ca PATH is the same exchange through a trusted certificate and a plain address instead. In code: Identity::generate(), Trust::by_address() / Trust::pin(fp) / Trust::anchor(pem), ServerTls::require_client(trust) for mutual identity, and IncomingMeta::peer to see who sent what.
Expected on stderr: delivered — QUIC's transport receipt for the request, not an application acknowledgement — and a trace id that also appears in the server's log line for the request.
Lines
| Line | Stations | Document |
|---|---|---|
| weida |
| Architecture |
| ZMQ |
| ZeroMQ (libzmq 4.3.5) — feature parity |
| NNG |
| nanomsg/NNG (SP v1, measured against NNG 1.4.0-rc.0) — feature parity |
| MQTT |
| MQTT 5.0 (OASIS Standard 2019-03-07, measured against rumqttd 0.20.0 and rmqtt 0.23.1) — feature parity |
| AMQP |
| AMQP 1.0 (OASIS Standard, 29 October 2012) — feature parity |
| NATS |
| Core NATS (client protocol, `nats-server` 2.14) — feature parity |
| base |
| 0014: Four parallel library workstreams, and bindings that follow each library |
Destinations
- Guide
0. The question: C8B1. One transfer, and what you may say about it2. Many peers, and the drop
- Reference
8 documents
ArchitecturePatternsweida wire protocol, version 0GuaranteesFailure modelInvariantsThe store interfaceImplementation
- Decisions
33 documents
0001: Sequence field — scope and layer0002: Control and bulk traffic — separation against head-of-line coupling0003: Flow-control credit — unit and layer0004: Durability levels for `Stored` and `Replicated`0005: The refusal race — closed as documented behaviour0006: Guarantee sets and explicit managed-resource boundaries0007: The topic namespace — opaque paths, segmented topic filters0008: Session identity — the proved fingerprint, and nothing elseand 25 more
- Libraries
12 documents
AMQP 1.0 for Python (python-qpid-proton 0.40.0) - feature parityAMQP 1.0 (OASIS Standard, 29 October 2012) — feature parityMQTT 5 for Python (paho-mqtt 2.x) — feature parityMQTT 5.0 (OASIS Standard 2019-03-07, measured against rumqttd 0.20.0 and rmqtt 0.23.1) — feature parityCore NATS for Python (nats-py 2.15.0) - feature parityCore NATS (client protocol, `nats-server` 2.14) — feature parityNNG for Python (pynng 0.9.0 over NNG 1.11.0) — feature paritynanomsg/NNG (SP v1, measured against NNG 1.4.0-rc.0) — feature parityand 4 more
- Adapters
3 documents
MQTT 5.0 — retired mappingNNG / SP v1 — retired mappingZMTP 3.1 — retired mapping
- Status
1. The roadmap2. What exists, layer by layer3. Progress by the numbers5. The measurements that decided something6. What needs a human7. Where the loop stands
- README
DocumentsCratesQuick start, without writing a programIdentity in one lineOther patternsNo reactor of your ownBuild and testThe websiteLicense