mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-10 13:01:29 +00:00
M3: a password prompt keeps a place in the open queue for its retry (#6731)
This commit is contained in:
1 parent
5aae0c3b82
commit
ba28458ad8
2 files changed
+37
-3
No files matched your search
@@ -142,12 +142,19 @@ impl PdfCraftApp {
|
||||
Ok(token)
|
||||
}
|
||||
|
||||
/// How many opens may wait for the worker: its bound, less one place while a password prompt
|
||||
/// is open, so the prompt's retry fits even before the worker has taken any of the others.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn open_slots(&self) -> usize {
|
||||
open_worker::MAX_QUEUED_OPENS - usize::from(self.password_prompt.is_some())
|
||||
}
|
||||
|
||||
/// Hand waiting files to the worker, oldest first, while its queue has room. Every queued
|
||||
/// job has a `pending_opens` entry, so fewer entries than the bound means room.
|
||||
/// job has a `pending_opens` entry, so fewer entries than [`Self::open_slots`] means room.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn submit_deferred_opens(&mut self) {
|
||||
let mut queue = std::mem::take(&mut self.deferred_opens);
|
||||
while self.deferred_opens.is_empty() && self.pending_opens.len() < open_worker::MAX_QUEUED_OPENS {
|
||||
while self.deferred_opens.is_empty() && self.pending_opens.len() < self.open_slots() {
|
||||
let Some(next) = queue.pop_front() else { break };
|
||||
self.open_path_request(&next.path, next.then, next.display_override);
|
||||
}
|
||||
@@ -866,7 +873,7 @@ impl PdfCraftApp {
|
||||
self.startup_superseded = true;
|
||||
// The worker queue is bounded. A long file list (a launch behind a password prompt,
|
||||
// or many files at once) waits here, in order, and is submitted as opens finish.
|
||||
if self.pending_opens.len() >= open_worker::MAX_QUEUED_OPENS || !self.deferred_opens.is_empty() {
|
||||
if self.pending_opens.len() >= self.open_slots() || !self.deferred_opens.is_empty() {
|
||||
self.deferred_opens.push_back(DeferredOpen { path: path.to_string(), then, display_override });
|
||||
return OpenOutcome::Pending;
|
||||
}
|
||||
|
||||
@@ -921,3 +921,30 @@ fn a_repeated_waiting_open_keeps_the_tool_it_brings() {
|
||||
assert_eq!(app.open_path(&path), crate::OpenOutcome::Pending);
|
||||
assert_eq!(app.deferred_opens.front().and_then(|d| d.then), Some("export.text"));
|
||||
}
|
||||
|
||||
/// A password prompt keeps a place in the worker's bounded queue for its retry: files named after
|
||||
/// the protected one fill the rest and wait in order, and the retry is queued, not refused as
|
||||
/// "too many documents are waiting to open" while the worker has yet to take the others.
|
||||
#[test]
|
||||
#[allow(clippy::expect_used)]
|
||||
fn a_password_prompt_keeps_a_place_in_the_open_queue_for_its_retry() {
|
||||
let mut harness = tool_open_harness();
|
||||
let held = HeldToolOpen::install(&mut harness);
|
||||
let locked = tool_open_file("queue-locked", "pdf", &encrypted_tool_fixture());
|
||||
harness.state_mut().open_path(&locked.0.to_string_lossy());
|
||||
held.wait_started();
|
||||
let others: Vec<ToolOpenFile> =
|
||||
(0..open_worker::MAX_QUEUED_OPENS + 4).map(|i| tool_open_file(&format!("queue-{i}"), "pdf", &fixture(1))).collect();
|
||||
for file in &others {
|
||||
harness.state_mut().open_path(&file.0.to_string_lossy());
|
||||
}
|
||||
held.complete(&mut harness);
|
||||
let app = harness.state();
|
||||
assert!(app.password_prompt.is_some(), "the protected file asks for its password");
|
||||
assert!(app.pending_opens.len() < open_worker::MAX_QUEUED_OPENS, "one place stays free: {} waiting", app.pending_opens.len());
|
||||
assert!(!app.deferred_opens.is_empty(), "the rest wait their turn");
|
||||
harness.state_mut().submit_password(Some("tool-password".into()));
|
||||
let app = harness.state();
|
||||
assert!(app.password_prompt.is_none(), "the retry is queued: {:?}", app.password_prompt.as_ref().and_then(|p| p.error.clone()));
|
||||
assert!(app.password_retry.is_some());
|
||||
}
|
||||
Reference in new issue
Block a user