Repository navigation
Conversation
…ed records A certified stream_collection_failed commit, and the commit after a transient manifest-drift skip, could advance a parent state stream while records of a child stream mapped to it were not in the store. Two causes: - handleStateMessage flushed only the named state stream. A child stream buffers under its own name, and a failed DONE does not flush it, so the parent cursor was staged and committed ahead of the child's records. It now flushes every buffered stream before staging state. - collectReportedOmissions did not report a stream whose batch was dropped for transient manifest drift, so decideCheckpointCommits saw no omission for the parent. That stream is now reported as a retryable omission, as a retryable SKIP_RESULT is. Tests: a child's records are stored before the parent commit of a certified failure, and a drift-dropped child batch withholds the parent checkpoint. Both fail on main. The collection-profile characterization test that pinned per-stream flushing now pins the flush-all contract. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
Add guard tests for the manifest-drift omission: a child that drops at DONE, after the parent's STATE, still withholds the parent, and a child's drift withholds only the parent it maps to. Assert the drift-dropped parent cursor is absent instead of merely different. Document the per-STATE flush cost and its spec basis at the flushAll call. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…stgres The drift helper and the certified-failure test acquired AS/RS listeners before their try/finally, so a failure in registration, token setup or connector-file creation left the listeners open. Each acquired resource now closes in its own finally, entered right after the acquisition. The three drift cases and the certified-failure case now also run against a disposable Postgres database when the dedicated Postgres test listener is configured, and assert which backend the run used. Without that listener the Postgres variants are reported as skipped, like the other Postgres-backed tests. Correct two comments: the STATE flush cost note claimed the same batches as before for interleaved streams, but batches are per stream; and the drift-at-DONE test comment misordered STATE and the child record. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A parent checkpoint could be committed while records of a child stream mapped to it were not in the store. Two paths led there (Collection Profile 0.2.0 §5.3: STATE is staged only after all prior records are durably written):
stream_collection_failedDONE.handleStateMessageflushed only the named state stream. The child buffers under its own name and a failed DONE does not flush it, so the parent cursor was staged and committed ahead of the child's records.not_foundfor a manifest-declared stream was recorded as a gap, butcollectReportedOmissionsdid not report it todecideCheckpointCommits. The parent that stream maps to saw no omission and committed.Root cause
The flush before staging state was scoped to one stream, but the commit invariant is scoped to a state stream and every child that maps to it. The drift skip was tracked in a separate set that the omission collector never read.
Change
reference-implementation/runtime/index.ts, two edits:handleStateMessage:flushBatch(stateStream)becomesflushAll().collectReportedOmissions: streams indriftSkippedStreamsare reported asretryable_skip.Tests
runtime-stream-collection-failed-commit.test.ts: the child's record is stored, and its batch event precedesrun.state_advanced, before the parent commit of a certified failure.runtime-ingest-manifest-drift.test.ts: a drift-dropped child batch leaves the parent cursor unchanged and records acheckpoint_withheldgap.collection-profile.test.ts: the characterization test that pinned per-stream flushing now pins flush-all (records_flushed2,buffered_records_dropped0).Guard tests in
runtime-ingest-manifest-drift.test.ts:The three drift tests fail with the omission line removed and pass with it. The drift withhold is whole-run, like a retryable
SKIP_RESULT: it does not compare a dropped record's position with the staged cursor, so a drop after STATE also withholds the parent. That is conservative (the window is re-collected, nothing is lost), and the second guard test pins it.Each Postgres variant runs against a disposable database on the dedicated Postgres test listener and asserts the backend in use. Without
PDPP_TEST_POSTGRES_URLthose variants are reported as skipped.With the per-stream flush restored, the certified-failure test fails on both SQLite and Postgres.
collection-profile.test.tsasserts the runtime's flush counters, which do not depend on storage, so it stays on SQLite.A wider run over 86 related test files showed one failure,
connector-failure-diagnostics.test.ts("stderr-bearing exit before DONE"). It fails the same way on unmodifiedmain: the Node deprecation warning adds stderr bytes the test does not expect.ultracite checkon the four touched files reports the same 5 errors and 79 warnings as the unmodified files.Risks
kbuffered streams and STATE emitted underBATCH_SIZE(500) records, that is up tokingest POSTs instead of 1. Streams that interleave records between STATEs pay this even when STATE is infrequent: for example, 2000 records spread evenly over four streams with a STATE for one stream every 1000 records make 5 POSTs before and 8 after (counting the terminal flush). DETAIL_COVERAGE and STREAM_EVIDENCE already flush every stream. Records are still written in arrival order per stream.checkpoint_stalledafter 3 runs. Before this change the child's records were lost silently while the parent advanced.Assisted-by: AI