Skip to content

feat(zero-rust): mutation-outcome listener, after Swift's - #216

Open
tmm wants to merge 1 commit into
mainfrom
feat/zero-rust-mutation-outcomes
Open

tmm wants to merge 1 commit into
mainfrom
feat/zero-rust-mutation-outcomes

Conversation

@tmm

@tmm tmm commented Nov 14, 2026

Copy link
Copy Markdown
Member

tmm's decision 2(b): Swift's mutation-outcome listener, ported to Rust.

let remove = zero.add_mutation_outcome_listener(|o: &MutationServerOutcome| {
    if let MutationOutcome::AppError { message, .. } = &o.outcome { show(&o.name, message) }
});

A mutation's server result settles with ZeroError when the client gives up connecting (disconnect_timeout_ms), yet the mutation is replayed after a reconnect. This listener hears its real outcome then, once per mutation, so an app has one place to show rejections. JS has no counterpart; this is Swift's addMutationOutcomeListener.

  • Which mutations: the ones this client ran. Rebased mutations, and mutations replayed from storage on launch, aren't reported, as in Swift.
  • When: the first server outcome (pushResponse, a mutationsPatch error, or lmid advancing). The server result settles first.
  • Lifetime: listeners live on Zero, so they survive an in-place client replacement.
  • Cost with no listeners: one map entry with the name per mutation. Args are moved, not copied.

Tests: tests/mutation_outcomes.rs, 4 tests:

  • each outcome is heard once;
  • a mutation replayed after the disconnect timeout is heard;
  • unsubscribe stops it;
  • listeners outlive a replaced client.

Each fails against a plausible wrong version: no dedupe, reporting from server, or attaching to the first engine only.

Benchmarks (mutations and pokes, 2 passes × 5 alternating rounds vs main): all within ±3.2%, with overlapping ranges.

Changeset: zero-rust minor (with 0.3.0).

Checked locally: clippy -D warnings, tests, docs, and conformance (66,384 cases, 0 failures).

Port zero-swift's addMutationOutcomeListener as
Zero::add_mutation_outcome_listener: the listener hears each mutation's
server outcome once, as a MutationServerOutcome, including that of a
mutation replayed after its server result settled with a ZeroError when
the client gave up connecting. The listeners belong to the Zero, so they
outlive a replaced client.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants