Skip to content

QUEUE-146: recover exact indexed entries across a sealed cycle - #1741

Draft
peter-lawrey wants to merge 5 commits into
fix/QUEUE-143-ordinary-append-rolls-past-eoffrom
feature/QUEUE-143-exact-index-eof-recovery
Draft

peter-lawrey wants to merge 5 commits into
fix/QUEUE-143-ordinary-append-rolls-past-eoffrom
feature/QUEUE-143-exact-index-eof-recovery

Conversation

@peter-lawrey

@peter-lawrey peter-lawrey commented Aug 24, 2026

Copy link
Copy Markdown
Member

Hold for final stack review. Keep this PR in draft until the repaired #1739 -> #1740 -> #1741 stack has fresh review and CI.

Purpose

Q3 of QUEUE-146: recover validated exact-index replication writes across sealed cycles, with CQE responsible for completion ordering and maintenance exclusion.

Contract

  • Ordinary writes retain Q1 publication selection and Q2's one-advance EOF behavior.
  • Every exact request receives read-only physical/publication classification before roll, EOF, cursor or appender mutation. Gaps are rejected; old published duplicates do not adopt unrelated later crash records.
  • An existing requested index is compared with the supplied payload, whether the original is already published or is a ready crash-written record beyond publication. Equal content is debug-only and silent when debug is disabled. Different content warns with both hex dumps; the supplied message is ignored without throwing for the mismatch or overwriting the original.
  • Valid ready crash records are adopted only through the requested sequence. Exact-next requests may adopt their contiguous predecessors.
  • Preflight derives the published sequence from the full write position, not a lossy paired sequence that may be stale yet alias the later position. General sparse-index repair is not provided.
  • Incomplete exact-next records may be recovered in place. EOF reopening uses expected-value CAS; legacy unpadded stores and terminal maximum-cycle EOF reopening are rejected before mutation.
  • Absence is not an empty existing store. Missing authoritative maxima and absent targets inside retained published bounds fail closed; creation outside those bounds follows the documented recovery policy.
  • Completion validates the shared cursor, takes a fresh physical snapshot, requires canonical one-to-one cycle filenames, and strictly reacquires surviving pathnames before sealing. It cannot certify an unlinked cached mapping.
  • Historical deletion has one refresh/retry. The current/highest roll is not a supported deletion target. Public cached range enumeration retains action-time endpoint existence checks.
  • Recovery lowers the normalization cursor; CQE must call the implementing appender's normaliseEOFs() before acknowledgement/completion and exclude destructive maintenance. The interface default remains a compatibility no-op.

Review corrections and evidence

  • readyCrashDuplicatesCompareMatchingAndDifferentPayloads covers matching and differing requested crash records, both with and without a published prefix, after reopening. readyCrashDuplicateEqualityIsSilentWhenDebugDisabled checks the disabled-debug behavior and retained mismatch warning. Tests assert both hex dumps, original contents, input cursor/limit preservation and adoption capped at the requested record.
  • These fixtures write genuinely ready records without publishing the store position. Like the existing interrupted-publication regression, they disable the optional acquisition-time CHECK_INDEX diagnostic, which assumes fully published state. They do not claim general index-repair coverage.
  • cachedCycleEnumerationRejectsDeletedBoundaries primes the cache and then deletes each endpoint without changing mapped metadata. It proves the old absent-path failure is preserved. The mapped-unlink case is POSIX-specific.
  • Existing regressions cover missing/ambiguous targets, stale aliased sequence publication, fresh enumeration after cache priming, non-canonical/duplicate cycle filenames, non-zero daily/hourly/weekly epochs, and disappearance of the currently mapped generation.
  • StoreAppenderInternalWriteBytesTest and WriteBytesIndexTest remain present, preserving cross-instance replay, reopen and live-tailer integration evidence.
  • Adjacent //! notes distinguish behavioral discriminators, retained integration evidence and precisely stated defensive branches without current discriminators. AsciiDoc uses direct //! comments.

Current ancestry and validation

  • Base: 9bd9b7e6db80b7d037a4f4a0f52f976c7dd4a4fe (fix/QUEUE-143-ordinary-append-rolls-past-eof).
  • Head: d1d639b7b190506a5175e078ead8b29af24c2108.
  • Base equals merge base; 20 changed files and no POM delta.
  • Existing branch history is preserved with a merge commit and a normal fast-forward push. The tree matches tested candidate 905a5440713a8d91753f51d3069ed396891938e7.
  • A fresh appender replaying a published second record could try to map the logical read limit near 128 TiB during duplicate-comparison cleanup. Restoring the read limit already restores the shared cursor; removing the redundant write-position setter avoids growing the file. publishedDuplicateAfterTwoRecordsDoesNotMapLogicalCapacity failed on the preceding code and passes here, checking unchanged file length/count and a subsequent append.
  • Full verification and local installation: 1,212 tests, zero failures/errors, 52 skipped. The initial run exposed a pre-existing tailer test race; the test now waits for its producer before checking later records. The full run then passed with retries disabled.
  • Linux amd64/OpenJDK 21.0.12, Maven 3.9.11, offline isolated Maven repository, -Dsurefire.rerunFailingTestsCount=0. Required build checks passed.
  • Wire runtime 2026.10-SNAPSHOT was rebuilt from merged Remove automatic roll shrinking code #1280 commit 3dd7fe5983c0133703ee72f57bced9a25270eb6f; JAR SHA-256 92803fb011f5071900f5c3b1b637cf39f6254e86b4e29f77f1256ecc96dde755. This is source-build evidence for the local run; released immutable coordinates remain a gate.
  • No Windows, macOS or ARM execution is claimed.

Stack and review gates

The repaired order is staged/develop -> #1739 -> #1740 -> #1741. #1741 remains draft for final-stack review. The coordinate work in #1750 and follow-ups #1745/#1746 are unchanged.

Wire #1280 merged on 2026-09-07. Successful CI on the published heads, independent review and immutable release/BOM coordinates remain outstanding. Previous-head results do not qualify the new heads.

@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 866e16a to f549546 Compare August 25, 2026 08:49
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from f549546 to cb19f48 Compare August 25, 2026 16:49
@peter-lawrey
peter-lawrey requested a review from tgd August 26, 2026 16:26
@peter-lawrey peter-lawrey self-assigned this Aug 26, 2026
@peter-lawrey
peter-lawrey marked this pull request as ready for review August 26, 2026 16:26
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from dd4b6f0 to e2233ab Compare August 26, 2026 16:35
@peter-lawrey peter-lawrey changed the title QUEUE-143: recover exact indexed entries across a sealed cycle QUEUE-146: recover exact indexed entries across a sealed cycle Aug 26, 2026
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch 2 times, most recently from a78780f to 21d293f Compare August 26, 2026 22:59
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 21d293f to 5177330 Compare August 27, 2026 09:11
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 5177330 to 81aa8e9 Compare August 27, 2026 13:37
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 81aa8e9 to 46fbeac Compare August 27, 2026 15:01
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 42a305c to 37efe0b Compare August 27, 2026 18:10
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch 2 times, most recently from 6ff1913 to eb7a26a Compare August 27, 2026 19:32
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from eb7a26a to 31d5164 Compare August 27, 2026 19:37
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 7282bdf to e14a3a1 Compare August 30, 2026 08:33
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from e14a3a1 to 62acf1a Compare August 30, 2026 19:44
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 62acf1a to ffd15dd Compare August 31, 2026 00:35
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from ffd15dd to fb11485 Compare August 31, 2026 13:07
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from fb11485 to 46dc4ff Compare August 31, 2026 20:58
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 46dc4ff to fac005d Compare September 1, 2026 03:27
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from fac005d to c36cb0a Compare September 1, 2026 03:56
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from c36cb0a to 399b1b7 Compare September 1, 2026 09:54
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from 399b1b7 to f522766 Compare September 1, 2026 15:34
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from f522766 to 7ad3ce7 Compare September 3, 2026 12:57
@peter-lawrey
peter-lawrey force-pushed the feature/QUEUE-143-exact-index-eof-recovery branch from c685e01 to 55904fd Compare September 4, 2026 16:39
Retain existing remote history while integrating the current parent.
Use the validated tree from 905a5440713a8d91753f51d3069ed396891938e7.

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.

1 participant