Exchange::accept enqueued a pending ack whenever !(duplicate && addressed && released) held, even when the backend store.insert returned Err (store full / backend error). On Err the released flag computed to false, so an ack was still enqueued: a receiver that did not keep the message acked it. For an addressed offer that releases the sender's custody for a message nobody holds; for a broadcast it fires a false confidence event at the sender. Gate the ack enqueue on res.is_ok(): enqueue only when the store actually retained the observation. The existing released-holder exception still applies among kept copies. No bounce is recorded on Err (already the case). Adds a unit test exercising a capped store (StoreError::Full) for both a broadcast and an addressed offer, and a tines-sim property that drives custody with CappedStore-backed nodes and asserts the "at least one holder" invariant still holds when stores fill.
23 lines
786 B
Rust
23 lines
786 B
Rust
//! tines-sim: a std simulator for the tines shared-memory library.
|
|
//!
|
|
//! `SimWorld` is a shared, reference-counted simulation of nodes connected by a
|
|
//! `ContactTrace`. `SimTransport` implements the `tines_core::Transport` trait
|
|
//! on top of that world: outbound frames are enqueued into per-node inboxes,
|
|
//! and `SimWorld::advance` turns contact-state changes into `Contact`/`Lost`
|
|
//! events. Loss and duplication are driven by a deterministic, seeded RNG so
|
|
//! that convergence behaviour is reproducible.
|
|
|
|
#![deny(warnings)]
|
|
|
|
pub mod capped;
|
|
pub mod sim;
|
|
pub mod trace;
|
|
pub mod transport;
|
|
pub mod world;
|
|
|
|
pub use capped::CappedStore;
|
|
pub use sim::{Sim, SimNode};
|
|
pub use trace::{Contact, ContactTrace};
|
|
pub use transport::SimTransport;
|
|
pub use world::{SimWorld, WorldConfig};
|