From 04b351a5fe3ba10233cc5bbeffee4690f388b51d Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Sun, 12 Jan 2025 15:12:50 +0100 Subject: [PATCH] Fix state setting after restart download --- src/client.rs | 3 ++- src/client_actor/util.rs | 28 +++++++++++++++++++--------- src/m3u8_download.rs | 10 ++++++---- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/client.rs b/src/client.rs index 38e6f1b..2b47305 100644 --- a/src/client.rs +++ b/src/client.rs @@ -164,6 +164,7 @@ impl Client { let file = util::open_or_create(&response.status(), &filename).await; // - download Data Ok( self.clone().store_body( file + , from as usize , content_type , response.body_mut() ).await? ) } @@ -207,10 +208,10 @@ impl Client { async fn store_body( self , mut file: File + , mut size: usize , content_type: Option , body: &mut ClientBody ) -> Result { let mut body = BodyDataStream::new(body); - let mut size = 0; let mut state = DownloadState::Partial { content_type: content_type.clone(), size }; loop { diff --git a/src/client_actor/util.rs b/src/client_actor/util.rs index 7af85e9..7880596 100644 --- a/src/client_actor/util.rs +++ b/src/client_actor/util.rs @@ -14,7 +14,7 @@ async fn process_next_result(mut actor: ClientActor, result: ClientTaskResult) - use ClientActorMessageHandle::{Download, GetData}; match result { - Err(e) => { + Err(mut e) => { info!("Retry failed download: {:?}", e); // retry ... instead of responing here we could also respond // with something that in turn would be used to retry... @@ -22,16 +22,26 @@ async fn process_next_result(mut actor: ClientActor, result: ClientTaskResult) - actor.tasks.spawn(async move { match e.action { Download { .. } => { - client.download( e.action.filename() - , &e.action.uri() - , &HeaderMap::new() ).await - . map_err(|source| ClientActorError::new(&e.action, source))?; - Ok(Some(e.action)) + let result = client.download( e.action.filename() + , &e.action.uri() + , &HeaderMap::new()).await; + match result { + Err(source) => Err(ClientActorError::new(&e.action, source)), + Ok(state) => { + e.action.set_state(state); + Ok(Some(e.action)) + }, + } }, GetData { .. } => { - client.data(&e.action.uri(), &HeaderMap::new()).await - . map_err(|source| ClientActorError::new(&e.action, source))?; - Ok(Some(e.action)) + let result = client.data(&e.action.uri(), &HeaderMap::new()).await; + match result { + Err(source) => Err(ClientActorError::new(&e.action, source)), + Ok(data) => { + *e.action.buffer_mut() = Some(data); + Ok(Some(e.action)) + }, + } }, } }); diff --git a/src/m3u8_download.rs b/src/m3u8_download.rs index 32d8318..c346274 100644 --- a/src/m3u8_download.rs +++ b/src/m3u8_download.rs @@ -45,10 +45,12 @@ impl TsPart { async fn download(&mut self, client: &ClientActorHandle) -> &Self { let state = client.download(self.filename.clone(), &self.uri).await; + debug!("TsPart::download got: {:?}", state); match state { Ok(DownloadState::Done { content_type, .. }) => { self.state = TsState::Ready; self.content_type = content_type; + debug!("DONE TsPart: {:?}", self); }, _ => self.state = TsState::Failed, }; @@ -98,14 +100,14 @@ impl M3u8Download { pub(super) async fn download(&mut self, client: &ClientActorHandle) { loop { let unfinished: Vec<_> = self.ts_parts.iter_mut() - . filter_map(|p| match p.state { - TsState::Ready => if p.content_type != Some("video/MP2T".to_string()) { - Some(p.download(client)) + . filter_map(|ts_part| match ts_part.state { + TsState::Ready => if ts_part.content_type != Some("video/MP2T".to_string()) { + Some(ts_part.download(client)) } else { None } - _ => Some(p.download(client)) + _ => Some(ts_part.download(client)) }).collect(); debug!("UNFINISHED NOW: {}", unfinished.len());