fix: hanging TUI on queueing downloads

This commit is contained in:
Michel de Graaf
2025-11-19 09:13:03 +01:00
parent 9f174c4c5e
commit f5b65053e2
2 changed files with 77 additions and 50 deletions
+10
View File
@@ -370,6 +370,16 @@ impl Client {
.unwrap_or_default()
}
/// Non-blocking variant that returns None if the lock is unavailable
pub fn try_get_search_results(
&self,
search_key: &str,
) -> Option<Vec<SearchResult>> {
self.context.try_read().ok().and_then(|ctx| {
ctx.searches.get(search_key).map(|s| s.results.clone())
})
}
pub fn get_all_searches(&self) -> HashMap<String, Search> {
self.context.read().unwrap().searches.clone()
}
+24 -7
View File
@@ -710,11 +710,29 @@ impl MainTui {
let timeout = self.search_timeout;
let selected_search_index = self.state.selected_search_index;
for (idx, search) in self.state.searches.iter_mut().enumerate() {
// Poll for new results
let search_query = search.query.clone();
let search_results = self.client.get_search_results(&search_query);
// Collect all queries first
let queries: Vec<(usize, String)> = self
.state
.searches
.iter()
.enumerate()
.map(|(idx, s)| (idx, s.query.clone()))
.collect();
// Fetch all results in one go (single lock acquisition per query)
// Use try_get_search_results to avoid blocking the UI thread
let all_results: Vec<(usize, Vec<_>)> = queries
.into_iter()
.filter_map(|(idx, query)| {
self.client
.try_get_search_results(&query)
.map(|results| (idx, results))
})
.collect();
// Now update state without holding any client locks
for (idx, search_results) in all_results {
if let Some(search) = self.state.searches.get_mut(idx) {
if !search_results.is_empty() {
search.results.clear();
for result in search_results {
@@ -742,7 +760,7 @@ impl MainTui {
}
}
// Mark as completed after timeout (but continue updating)
// Mark as completed after timeout
if search.status == SearchStatus::Active
&& search.start_time.elapsed() > timeout
{
@@ -750,6 +768,7 @@ impl MainTui {
}
}
}
}
fn queue_selected_downloads(&mut self) {
let selected_files: Vec<(String, String, u64)> = self
@@ -776,7 +795,6 @@ impl MainTui {
let download_dir = self.download_dir.clone();
let sender = self.state.downloads_sender_channel.clone().unwrap();
thread::spawn(move || {
thread::spawn(move || {
for (filename, username, size) in selected_files.into_iter() {
match client.download(
@@ -797,7 +815,6 @@ impl MainTui {
}
}
});
});
// Clear selection
self.state.results_selected_indices.clear();