Repository navigation
2.1.1
Patch release: dependency updates, Rust 1.91.0 MSRV alignment, deterministic
simulation CI migration, and WebSocket/WSS upgrade-path buffering fixes.
✨ Added
test(sim): moonpool-sim-driven deterministic UDP simulation. A new
test-only workspace cratesim/(sozu-sim,publish = false) hosts a
deterministic simulation of the sans-io UDP core
(sim/tests/udp_simulation.rs) driven by themoonpool-sim
engine (seeded runtime, virtual clock, RNG,buggifyfault injection). It
ports the former handmade harness's weighted action grammar, shadow model,
cross-step invariants and determinism guard onto moonpool, keeping the
SOZU_UDP_SIM_SEED/_SEEDS/_STEPSreplay/sweep knobs, and replaces it:
the handmadelib/tests/udp_simulation.rsis removed — moonpool is now the
sole UDP deterministic-sim.lib//bin/stay async-free: moonpool/tokio are
sim/dev-dependencies only.moonpool-sim
is pinned to a git rev (the published 0.7.0 doesn't build on stable;main
does) — swapping to a crates.io release later is a follow-up, not a blocker.
🔄 Changed
- MSRV bumped 1.88.0 → 1.91.0 (
rust-toolchain+ every crate's
rust-version). Required bymoonpool-sim, which usesDuration::from_hours
/from_mins— const-stable only since Rust 1.91. moonpool also needs
--cfg tokio_unstable(it seeds tokio's runtime RNG via the unstableRngSeed
API for scheduler determinism), but it is scoped to thesozu-simbuild
only — the moonpool dev-deps live under[target.'cfg(tokio_unstable)'.dev-dependencies]
and the harness is#![cfg(tokio_unstable)]-gated, socargo test --workspace
and every production build stay free of the flag (the sweep sets it via
RUSTFLAGS). No workspace-wide.cargo/config.toml. chore(lint): resolved the Rust 1.91 clippy lints (collapsible_if,
manual_is_multiple_of,derivable_impls,mismatched_lifetime_syntaxes)
surfaced acrosslib/command/binby the MSRV bump. No behavior change.
🐛 Fixed
fix(pipe): WebSocket/WSS server-first frames are flushed after101 Switching Protocols.
The post-upgrade pipe now arms writable readiness when bytes enter either
sozu-owned direction buffer, so edge-triggered epoll cannot park a backend
frame such as Pusher/Reverbconnection_establisheduntil the client sends
its first WebSocket frame. It also arms writable readiness for bytes already
inherited from the H1 mux during upgrade, including a backend frame carried in
the same read buffer as the101 Switching Protocolsresponse.
🤖 CI
ci(sim): the moonpoolsozu-simsweep is the sole UDP swarm. A per-PR
udp-simulationjob runs a modest seeded sweep (with--cfg tokio_unstable),
and the nightlysimulation-sweepworkflow goes deep — seed-bounded to fit the
45-min cap, since moonpool's per-seed tokio-runtime construction is ~100× slower
per seed-step than the former pure-sync handmade swarm. All CI toolchain pins
move 1.88.0 → 1.91.0.
🔐 Security
chore(deps): bumpanyhow1.0.102 → 1.0.103 for
RUSTSEC-2026-0190
(unsoundness inError::downcast_mut()afterError::context()). Lockfile-only
— the workspace^1.0.102requirement already permitted it; restores a green
cargo audit --deny warnings.