Fixed long-running requests to be cancelled when users try to change tabs or contexts.
This commit is contained in:
@@ -16,6 +16,7 @@ mod tests {
|
||||
|
||||
assert_eq!(app.navigation_stack, vec![DEFAULT_ROUTE]);
|
||||
assert!(app.network_tx.is_none());
|
||||
assert!(!app.cancellation_token.is_cancelled());
|
||||
assert_eq!(app.error, HorizontallyScrollableText::default());
|
||||
assert!(app.response.is_empty());
|
||||
assert_eq!(app.server_tabs.index, 0);
|
||||
@@ -82,6 +83,19 @@ mod tests {
|
||||
assert!(app.is_routing);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reset_cancellation_token() {
|
||||
let mut app = App::default();
|
||||
app.cancellation_token.cancel();
|
||||
|
||||
assert!(app.cancellation_token.is_cancelled());
|
||||
|
||||
let new_token = app.reset_cancellation_token();
|
||||
|
||||
assert!(!app.cancellation_token.is_cancelled());
|
||||
assert!(!new_token.is_cancelled());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reset_tick_count() {
|
||||
let mut app = App {
|
||||
|
||||
+15
-1
@@ -3,6 +3,7 @@ use log::{debug, error};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
use tokio::time::Instant;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::app::radarr::{ActiveRadarrBlock, RadarrData};
|
||||
use crate::models::{HorizontallyScrollableText, Route, TabRoute, TabState};
|
||||
@@ -19,6 +20,7 @@ const DEFAULT_ROUTE: Route = Route::Radarr(ActiveRadarrBlock::Movies, None);
|
||||
pub struct App<'a> {
|
||||
navigation_stack: Vec<Route>,
|
||||
network_tx: Option<Sender<NetworkEvent>>,
|
||||
cancellation_token: CancellationToken,
|
||||
pub server_tabs: TabState,
|
||||
pub error: HorizontallyScrollableText,
|
||||
pub response: String,
|
||||
@@ -36,10 +38,15 @@ pub struct App<'a> {
|
||||
}
|
||||
|
||||
impl<'a> App<'a> {
|
||||
pub fn new(network_tx: Sender<NetworkEvent>, config: AppConfig) -> Self {
|
||||
pub fn new(
|
||||
network_tx: Sender<NetworkEvent>,
|
||||
config: AppConfig,
|
||||
cancellation_token: CancellationToken,
|
||||
) -> Self {
|
||||
App {
|
||||
network_tx: Some(network_tx),
|
||||
config,
|
||||
cancellation_token,
|
||||
..App::default()
|
||||
}
|
||||
}
|
||||
@@ -102,6 +109,12 @@ impl<'a> App<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset_cancellation_token(&mut self) -> CancellationToken {
|
||||
self.cancellation_token = CancellationToken::new();
|
||||
|
||||
self.cancellation_token.clone()
|
||||
}
|
||||
|
||||
pub fn pop_and_push_navigation_stack(&mut self, route: Route) {
|
||||
self.pop_navigation_stack();
|
||||
self.push_navigation_stack(route);
|
||||
@@ -117,6 +130,7 @@ impl<'a> Default for App<'a> {
|
||||
App {
|
||||
navigation_stack: vec![DEFAULT_ROUTE],
|
||||
network_tx: None,
|
||||
cancellation_token: CancellationToken::new(),
|
||||
error: HorizontallyScrollableText::default(),
|
||||
response: String::default(),
|
||||
server_tabs: TabState::new(vec![
|
||||
|
||||
+9
-1
@@ -752,10 +752,18 @@ impl<'a> App<'a> {
|
||||
self.dispatch_by_radarr_block(&active_radarr_block).await;
|
||||
}
|
||||
|
||||
if self.is_routing || self.tick_count % self.tick_until_poll == 0 {
|
||||
if self.is_routing {
|
||||
if self.is_loading {
|
||||
self.cancellation_token.cancel();
|
||||
}
|
||||
|
||||
self.dispatch_by_radarr_block(&active_radarr_block).await;
|
||||
self.refresh_metadata().await;
|
||||
}
|
||||
|
||||
if self.tick_count % self.tick_until_poll == 0 {
|
||||
self.refresh_metadata().await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn refresh_metadata(&mut self) {
|
||||
|
||||
+35
-16
@@ -1115,17 +1115,6 @@ mod tests {
|
||||
assert!(!app.data.radarr_data.prompt_confirm);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_radarr_on_tick_not_routing() {
|
||||
let mut app = App::default();
|
||||
|
||||
app
|
||||
.radarr_on_tick(ActiveRadarrBlock::Downloads, false)
|
||||
.await;
|
||||
|
||||
assert!(!app.is_routing);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_radarr_on_tick_routing() {
|
||||
let (mut app, mut sync_network_rx) = construct_app_unit();
|
||||
@@ -1159,6 +1148,41 @@ mod tests {
|
||||
assert!(!app.data.radarr_data.prompt_confirm);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_radarr_on_tick_routing_while_long_request_is_running_should_cancel_request() {
|
||||
let (mut app, mut sync_network_rx) = construct_app_unit();
|
||||
app.is_routing = true;
|
||||
app.is_loading = true;
|
||||
|
||||
app
|
||||
.radarr_on_tick(ActiveRadarrBlock::Downloads, false)
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
sync_network_rx.recv().await.unwrap(),
|
||||
RadarrEvent::GetDownloads.into()
|
||||
);
|
||||
assert_eq!(
|
||||
sync_network_rx.recv().await.unwrap(),
|
||||
RadarrEvent::GetQualityProfiles.into()
|
||||
);
|
||||
assert_eq!(
|
||||
sync_network_rx.recv().await.unwrap(),
|
||||
RadarrEvent::GetTags.into()
|
||||
);
|
||||
assert_eq!(
|
||||
sync_network_rx.recv().await.unwrap(),
|
||||
RadarrEvent::GetRootFolders.into()
|
||||
);
|
||||
assert_eq!(
|
||||
sync_network_rx.recv().await.unwrap(),
|
||||
RadarrEvent::GetDownloads.into()
|
||||
);
|
||||
assert!(app.is_loading);
|
||||
assert!(!app.data.radarr_data.prompt_confirm);
|
||||
assert!(app.cancellation_token.is_cancelled());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_radarr_on_tick_should_refresh() {
|
||||
let (mut app, mut sync_network_rx) = construct_app_unit();
|
||||
@@ -1187,10 +1211,6 @@ mod tests {
|
||||
.radarr_on_tick(ActiveRadarrBlock::Downloads, false)
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
sync_network_rx.recv().await.unwrap(),
|
||||
RadarrEvent::GetDownloads.into()
|
||||
);
|
||||
assert_eq!(
|
||||
sync_network_rx.recv().await.unwrap(),
|
||||
RadarrEvent::GetQualityProfiles.into()
|
||||
@@ -1208,7 +1228,6 @@ mod tests {
|
||||
RadarrEvent::GetDownloads.into()
|
||||
);
|
||||
assert!(app.is_loading);
|
||||
assert!(!app.data.radarr_data.prompt_confirm);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user