Skip to content

Rust correctness: three small bugs (watch_loop first tick, now_iso label, cursor diff) #337

Description

@willwashburn

Context

Three small but real correctness issues flagged in the May 2026 Rust review.

1. watch_loop.rs:233-236 — first periodic tick comes 2× interval late when not immediate

// crates/relayburn-sdk/src/ingest/watch_loop.rs:233-236
iv.tick().await; // skip the immediate-fires-now tick
                 // we already ran one above

The comment says "we already ran one above" — but immediate==false means we didn't. So the first periodic tick comes 2 * interval after start. Move the iv.tick().await skip inside if immediate, or use interval_at(now + interval, ...) for the non-immediate branch.

2. ledger/writer.rs:26-38 now_iso doesn't emit ISO

The function name is now_iso and the written_at column comment in ledger/schema.rs:124 describes it as wall-clock ISO. The implementation actually emits ts:00000001234567890.123456789 (the comment in the body admits it). Nothing currently parses it as ISO, but the discrepancy will bite the next porter.

Fix: either rename the function (and the column doc) to match what it actually emits (a sortable monotonic timestamp), or change it to actually emit ISO via time::format_description::well_known::Iso8601. The latter coordinates with #(civil-date math consolidation).

3. ingest/cursors.rs:166-175 save_cursor_changes lies in its doc

Doc says: "Persist only the keys whose cursor value differs."

Impl is:

if before == after { Ok(()) } else { save_cursors(after) }

So it's just an early-return-if-equal, with save_cursors writing the whole map regardless. Either implement actual diffing or drop the helper and have callers compare-then-save inline.

This compounds with the upstream let mut after = before.clone() deep-clone-and-diff pattern at ingest/ingest.rs:164, 200, 219, 238, 317 — each call clones a BTreeMap<String, Value> deeply.

Proposed fix

Three small, independent commits — fine as one PR or three. The watch-loop fix is the only behavior change a user could notice; the other two are doc/naming hygiene.

References

  • crates/relayburn-sdk/src/ingest/watch_loop.rs:233-236
  • crates/relayburn-sdk/src/ledger/writer.rs:26-38, crates/relayburn-sdk/src/ledger/schema.rs:124
  • crates/relayburn-sdk/src/ingest/cursors.rs:166-175, ingest/ingest.rs:164, 200, 219, 238, 317
  • Review notes from the May 2026 Rust review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions