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)
|
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
|
/// 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"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
fn submit_deferred_opens(&mut self) {
|
fn submit_deferred_opens(&mut self) {
|
||||||
let mut queue = std::mem::take(&mut self.deferred_opens);
|
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 };
|
let Some(next) = queue.pop_front() else { break };
|
||||||
self.open_path_request(&next.path, next.then, next.display_override);
|
self.open_path_request(&next.path, next.then, next.display_override);
|
||||||
}
|
}
|
||||||
@@ -866,7 +873,7 @@ impl PdfCraftApp {
|
|||||||
self.startup_superseded = true;
|
self.startup_superseded = true;
|
||||||
// The worker queue is bounded. A long file list (a launch behind a password prompt,
|
// 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.
|
// 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 });
|
self.deferred_opens.push_back(DeferredOpen { path: path.to_string(), then, display_override });
|
||||||
return OpenOutcome::Pending;
|
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.open_path(&path), crate::OpenOutcome::Pending);
|
||||||
assert_eq!(app.deferred_opens.front().and_then(|d| d.then), Some("export.text"));
|
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