Repository navigation
Conversation
ciaranra
force-pushed
the
fix/shot-end-failure-latches
branch
from
October 6, 2026 03:55
91701f5 to
500b613
Compare
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.
Fixes #1036.
SeleneRuntimemust not certify a shot, or keep running work, after a native lifecycle call failed. Two calls broke that.shot_endshot_endtakesactive_shotbefore calling the plugin'sshot_end_fn. When the descriptor lookup or the native call failed, the error was returned but not latched, so a secondshot_end()found no active shot, skipped the plugin and returnedOk(Shot). Now the failure latches the runtime's failure state (batch_failure) and returns the real error. Every operation, including anothershot_end, errors until a reset succeeds, because the plugin may have partly finalized the shot.Plugin
initOn the flat and metadata routes,
prepare_runtime_inputruns outsidewith_native_mutation, so a failedinit_fn(nonzero errno, or success with a null handle) was not latched either:shot_endthen certified an empty shot for a plugin that never started, and later input retriedinitwithout a reset. Both init failures now latch too. Ordinary input rejections (capacity, duplicate allocation) are unchanged.A sweep of the other plugin lifecycle calls found them already latched (lowering, draining, measurement delivery and
shot_startrun underwith_native_mutation; a failedexitlatches since #1034).QisEnginealready latched ashot_endfailure at engine level, so through the engine the shot_end case was only reachable by usingSeleneRuntimedirectly.Tests
Both run in a child process, because the descriptor fixture is process-wide.
failed_shot_end_is_never_certified_on_retry: the plugin'sshot_endfails once (errno 9), andrxyandshot_endcalls are counted. On every lowering route: the firstshot_end()reports the error; a retry fails with no second native call; a validX(0)reports the latched error and never reaches the plugin; after a successful reset a full shot runs and finalizes for real. Removing the latch fails at the retry; removing it and skipping the retry check fails atX(0).failed_init_is_latched_until_reset(replaces the null-instance test from Keep qubit handles live through measurement and start every qubit lifetime with exactly one prep #1017): for an init that returns errno 5 and one that returns success with a null handle, on every route: the error names the failure,shot_end()fails, and further input reports the latched error without callinginitagain. Removing the init latch fails atshot_end().Verification
cargo test --locked -p pecos-qiswith and withoutselene-runtimes(248 unit tests), workspace clippy with-D warnings,cargo fmt --check, pre-commit.just pytest-ci-coreandjust rslib-rust-test.shot_end, aQisEnginereset whose runtimeexitalso fails drops the engine's terminal error, soget_resultsreturns the failed shot.