4.2 KiB
| cairn | change | date |
|---|---|---|
| log | pimdir-queue-visibility | 2026-08-27 |
A staged write shows on the next read, not on the next sync
pimdir-producer-reader made Himalaya a reader and a producer, and left the two halves unconnected: a write went to the store's queue, a read projected the committed index, and nothing joined them. Flag a message and the flag was gone from the listing until Neverest ran. Capabilities backends and commands moved.
What landed
-
Reads go through an overlaying
PimdirReader(capabilitybackends).PimdirClientholds the reader role rather than a store handle, so the backend carries no write at all, and builds it withwith_pending(), so a stagedset-flags,update,remove,moveorcopyshows on the next read. Every one of those addresses a message that already exists and keeps its public id, so nothing changed about how a message is addressed andEnvelope.idis still aString. -
A queued creation is reported, not listed. It has no
sequntil the owner applies it, and no placeholder went intoEnvelope.id:0and""are values in the identifier space that name nothing, and aq-prefixed token is an id from another space in the field every command reads back.Envelopescarries aqueuedcount instead, rendered under the table as "N queued messages, seehimalaya pimdir queue list" and serialized for--json. Zero for every other backend, which is the truth about a backend whose writes reach the server as they are made, so the field stays least-common-denominator rather than pimdir trivia.envelope searchreports none whatever the backend, because a queued creation is never matched against the query and a count the filter never saw would be worse than no count. -
himalaya pimdir queue list(capabilitycommands), rendering a queued creation as mail. Thepimdirbinary is kind-agnostic and prints ids, hashes and flags on purpose; this client holds the conventions and the blobs, so it reads the flags, subject and recipient out of the action's ownv: 1summary and shows when the row was queued. The row id is in a ROW column, named for what it is: it addresses a pending action, not a message, and the message gets a different id when the owner applies it. -
himalaya pimdir queue cancel <row>, through io-pimdir's scoped owner operation, confirming unless--yes. It is the only retraction a queued creation has: a staged flag or move is undone by doing the opposite,set-flagsbeing absolute rather than a delta, but a message that does not exist yet cannot be deleted. A sync in flight owns the store, and that is reported as a sync running with the action possibly already applied, rather than as a lock error. -
message saveis unchanged. The shared commands do not vary their wording by backend.
What did not land
Envelope.id: Option<String> — whether a queued creation belongs in envelope list at all is a v1 question, and widening the shared envelope for every backend before the drafts UX says it must is not worth it. If the answer turns out to be yes, null is the encoding, and it is an additive change at that point.
Draining, again, and it is worth writing down why: the queue carries no source column, the drainer stamps its own, and bindings are keyed (collection, link_id, source). Himalaya has no source to stamp since pimdir-producer-reader replaced pimdir.source with pimdir.account, so it cannot drain correctly even in principle.
A defect this found upstream
io-pimdir's overlaid page could come back short in the middle of a collection, because a staged removal dropped a row the statement had returned. scan_items pages until a short page, as every consumer of a keyset page does, so one staged deletion would have ended a whole-collection scan early and silently dropped every message past it. Fixed upstream in io-pimdir's overlay-page-is-total before this landed; this change depends on it.
Tests
src/pimdir/backend.rs: a queued creation renders as mail with an empty id, its subject, recipient and Message-ID read from the staged summary; and only a creation renders in that view, a staged removal having nothing to show there since it addresses a message the listing already reflects.
118 tests pass.