Verify preview admission bounds under contention and worker unwind
This commit is contained in:
1 parent
ec75a52cf7
commit
c8e611081f
2 files changed
+55
-2
No files matched your search
@@ -413,6 +413,51 @@ pub fn error_response(status: StatusCode) -> Response<Vec<u8>> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn concurrent_admission_stays_bounded_and_unwind_releases_capacity() {
|
||||
let registry = Arc::new(PreviewRegistry::default());
|
||||
let active = Arc::new(AtomicUsize::new(0));
|
||||
let barrier = Arc::new(std::sync::Barrier::new(8));
|
||||
let workers: Vec<_> = (0..8)
|
||||
.map(|_| {
|
||||
let registry = registry.clone();
|
||||
let active = active.clone();
|
||||
let barrier = barrier.clone();
|
||||
std::thread::spawn(move || {
|
||||
barrier.wait();
|
||||
for _ in 0..500 {
|
||||
if let Some(admission) = registry.admit() {
|
||||
let count = active.fetch_add(1, Ordering::SeqCst) + 1;
|
||||
assert!(count <= MAX_REQUESTS);
|
||||
std::thread::yield_now();
|
||||
active.fetch_sub(1, Ordering::SeqCst);
|
||||
drop(admission);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
for worker in workers {
|
||||
worker.join().unwrap();
|
||||
}
|
||||
assert_eq!(active.load(Ordering::SeqCst), 0);
|
||||
assert_eq!(registry.requests.load(Ordering::SeqCst), 0);
|
||||
let first = registry.admit().unwrap();
|
||||
let interrupted = registry.clone();
|
||||
assert!(std::panic::catch_unwind(move || {
|
||||
let _second = interrupted.admit().unwrap();
|
||||
panic!("injected preview worker panic");
|
||||
})
|
||||
.is_err());
|
||||
let second = registry
|
||||
.admit()
|
||||
.expect("Unwinding must release the second slot");
|
||||
assert!(registry.admit().is_none());
|
||||
drop(first);
|
||||
drop(second);
|
||||
assert_eq!(registry.requests.load(Ordering::SeqCst), 0);
|
||||
}
|
||||
|
||||
struct Fixture {
|
||||
_directory: tempfile::TempDir,
|
||||
database: PathBuf,
|
||||
|
||||
+10
-2
@@ -21,7 +21,8 @@ Index-change notifications also advance the preview selection identity, so a
|
||||
same-path image/recording reloads rather than retaining previously decoded media.
|
||||
Failed native preview preparation and image/audio/video loading now offer an explicit **Retry preview**
|
||||
button. It invalidates the old request revision and cannot restart a selection
|
||||
that has since changed. There is no automatic retry loop. The added regression
|
||||
that has since changed. Busy preparation receives at most one delayed retry;
|
||||
other failures require explicit user action, with no unbounded retry loop. The added regression
|
||||
passed with all 60 frontend tests, formatting and the production frontend build.
|
||||
|
||||
This does not hash every recording on every request. A same-size/mtime in-place
|
||||
@@ -53,7 +54,7 @@ for these protocol regressions.
|
||||
Ubuntu 24.04 WSL compiled the immutable `370db7e` Git snapshot with the locked
|
||||
dependencies and `SEARCHI_FORCE_CPU=1`. All nine preview tests passed in 0.73 s;
|
||||
the complete native desktop suite then passed 45/45 in 2.78 s, with no skips.
|
||||
The native source tree remains identical to that snapshot; subsequent commits
|
||||
At the time of validation the native source tree matched that snapshot; subsequent commits
|
||||
changed frontend retry behavior only. Compilation took 8m 18s after missing
|
||||
locked dependencies were fetched. An initial offline attempt could not resolve
|
||||
the uncached Single-Instance plugin; it was not a product test failure.
|
||||
@@ -69,3 +70,10 @@ The existing vendored GLib code emitted 34 compiler warnings. This was a debug
|
||||
Rust test build, not strict Linux Clippy, a packaged desktop launch, WebKit
|
||||
playback, GPU inference or macOS validation. No model inference was executed.
|
||||
Native custom-protocol playback and seeking remain open on all release systems.
|
||||
|
||||
A subsequent Windows CPU concurrency regression ran eight threads with 500
|
||||
admission attempts each and checked that no more than two admitted jobs overlap.
|
||||
It also injected a worker unwind and verified that capacity is released rather
|
||||
than remaining busy. All 46 native tests passed in 1.04 s and strict all-target
|
||||
Clippy passed. This added test was not included in the earlier Linux 45-test
|
||||
snapshot; no additional production protocol behavior changed.
|
||||
Reference in new issue
Block a user