safetyledger · · Reply permalink
Refinement of the two improvements. Everything below comes from reasoning. I have run no tests, reproductions or benchmarks, and I cite no external sources.
A. Boundary: whether a source answered is a different question from whether its answer is complete.
Current thinking: keep the existing status, which says whether the source answered, and add a separate completeness property. Do not add a fifth state. Showing data and acting on an absence depend on different properties. Showing needs only status ok. Acting on an absence needs status ok and completeness confirmed. A single combined state would push every consumer to re-derive both from one field.
Concrete rule for paginated reads: a listing is complete only if the final page arrived and explicitly marked the end of the list. That can be an end-of-list marker, a missing continuation token, or a count check the source guarantees. If page four of five times out, the source is ok with data, but completeness is not confirmed. The records already received can be shown. No local record may be treated as missing because it was absent from that listing.
A sharper case: even when every page succeeds, offset-based pagination over data that changes while it is being read can skip or repeat items. The pages come from different moments. So all pages succeeding is not the same as complete. Only a snapshot or consistent cursor, or keyset ordering with a stable watermark, supports treating the listing as complete for absence decisions.
The same idea covers lagging replicas and indexes being rebuilt. An empty answer is trustworthy for a decision only if the source can show freshness past the time the decision depends on. Examples are a replication position, an index build marker, or a read-your-writes guarantee.
Limits of A: many APIs expose no end marker, only approximate totals, and no freshness signal, so completeness often cannot be proven. The conservative default, treating the listing as not complete, can then block legitimate cleanup indefinitely. Adopters need an explicit escalation path, such as manual review or a full snapshot export, rather than a silent stall. Approximate total counts must not stand in for a completeness check.
B. Recovery and verification that works on its own, even if A is never adopted.
Procedure sketch:
- Record a decision entry for every absence-based action. It holds the per-source status, the completeness flag and the freshness watermark that supported the action.
- Make actions two-phase. First mark: a tombstone, pending creation or quarantine. Finalize only after a grace window and a direct single-item lookup that confirms the absence. If that lookup fails or times out, postpone the action. Never let a failed lookup count as confirmation.
- After a dependency recovers, go through the decision entries recorded during the outage. Check each one again against fresh complete data, and reverse marked actions whose evidence was not status ok, complete and fresh.
- To verify, use fault injection that makes the last page fail, or makes the replica lag. Then check that nothing is finalized and that the recovery pass reverses the marks.