refactor(consensus)!: promote AdvanceOutOfRange to a typed variant#571
Closed
SebastianThiebaud wants to merge 1 commit into
Closed
refactor(consensus)!: promote AdvanceOutOfRange to a typed variant#571SebastianThiebaud wants to merge 1 commit into
SebastianThiebaud wants to merge 1 commit into
Conversation
The shared pre-persist range guard previously surfaced its rejection
through `ConsensusError::PermanentDriver(Box::new(AdvanceOutOfRange(_)))`,
forcing every consumer that wanted to identify this single well-known
condition to `downcast_ref` (and a test to `expect()` that the downcast
succeeded — a contract assertion the type system should enforce for free).
Promotes the condition to its own variant `ConsensusError::AdvanceOutOfRange
{ at_least: u64 }` and threads the typed value end-to-end:
* `reject_out_of_range_advance` returns the variant directly — no
`Box::new`, no string formatting at the boundary.
* `PersistDisposition` gains a matching `AdvanceOutOfRange { at_least }`
variant so the server-side classifier does NOT re-box into
`PersistDisposition::Permanent(Box<dyn Error>)`.
* `service::extend_window` and `fence::run_leader_watch` get a new
compiler-forced arm. Wire disposition is unchanged (INTERNAL,
must-not-retry — same as `PermanentDriver` produced before); the gRPC
status message now names the offending `at_least` value directly
instead of routing it through `source.to_string()`.
* Removes the now-unused standalone `pub struct AdvanceOutOfRange(pub
u64)` (and its `pub use`). The three driver tests that previously
matched `ConsensusError::PermanentDriver(_)` for the range-guard case
now match the typed variant including the surfaced `at_least` value;
the four `PermanentDriver(_)` matchers covering real driver faults
(I/O failure, fsync panic, apply-task-gone) are left alone.
BREAKING CHANGE: `ConsensusError` is not `#[non_exhaustive]`, so adding a
variant is a SemVer break for external pattern matchers. The previously
re-exported `tsoracle_consensus::AdvanceOutOfRange` struct is removed —
match on `ConsensusError::AdvanceOutOfRange { at_least }` instead.
Signed-off-by: Sebastian Thiebaud <sebastian@prismarisk.com>
Contributor
Author
|
Superseded by #569, which landed the same refactor (typed end-to-end) on main first. Closing in favor of the merged variant. |
Coverage Report for CI Build 26494519362Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage decreased (-0.05%) to 94.857%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
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.
Summary
ConsensusError::PermanentDriver(Box::new(AdvanceOutOfRange(_))), forcing every consumer that wanted to identify this one well-known condition todowncast_ref(and a test toexpect()that the downcast succeeded — a contract assertion the type system should enforce for free).ConsensusError::AdvanceOutOfRange { at_least: u64 }and threads the typed value end-to-end:reject_out_of_range_advancereturns the variant directly — noBox::new, no string formatting at the boundary.PersistDispositiongains a matchingAdvanceOutOfRange { at_least }variant so the server-side classifier does not re-box intoPersistDisposition::Permanent(Box<dyn Error>).service::extend_windowandfence::run_leader_watchget a new compiler-forced arm. Wire disposition is unchanged (INTERNAL, must-not-retry — exactly whatPermanentDriverproduced before); the gRPC status message now names the offendingat_leastvalue directly instead of routing it throughsource.to_string().pub struct AdvanceOutOfRange(pub u64)and itspub use. The three driver-level tests that previously matchedConsensusError::PermanentDriver(_)for the range-guard case now match the typed variant including the surfacedat_leastvalue; the fourPermanentDriver(_)matchers covering real driver faults (I/O failure, fsync panic, apply-task-gone) are left alone — they continue to test what they were meant to test.After this change, every remaining
Box<dyn std::error::Error + Send + Sync>carried byConsensusErroris genuinely-opaque driver internals (rocksdb errors, tonic errors, omnipaxos errors, file I/O) — the closed-shapeAdvanceOutOfRangeno longer hides in there.Breaking change
ConsensusErroris not#[non_exhaustive], so adding a variant is a SemVer break for external pattern matchers. The previously re-exportedtsoracle_consensus::AdvanceOutOfRangestruct is removed — match onConsensusError::AdvanceOutOfRange { at_least }instead. No in-repo callers imported the struct directly, so the in-tree migration is mechanical.Test plan
cargo build --workspace --all-features— cleancargo test --workspace --all-features— zero failurescargo clippy --workspace --all-features --all-targets -- -D warnings— cleancargo fmt --check— clean (pre-commit hook enforced)reject_out_of_range_advance_rejects_above_the_cap_as_typed_variantmatches the variant with the exactat_leastvalue (nodowncast_ref)advance_out_of_range_threads_typed_value_through_classifyproves the value flows typed across the consensus → server boundary without re-boxingConsensusError::AdvanceOutOfRange { at_least } if at_least == PHYSICAL_MS_MAX + 1(stronger than the previousmatches!(_, PermanentDriver(_)))