From 240e5563a3db767fccccfe523af74a8d862f5da0 Mon Sep 17 00:00:00 2001 From: Alexandru Dracea Date: Wed, 28 Dec 2022 15:44:45 +0200 Subject: [PATCH 1/6] Add error handling and retry attempts Handles cases where the segments fail to download and sometimes get stuck by introducing a timeout and retrying on failure. --- crunchy-cli-core/src/cli/utils.rs | 51 +++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/cli/utils.rs b/crunchy-cli-core/src/cli/utils.rs index 1f6bf40..3d14318 100644 --- a/crunchy-cli-core/src/cli/utils.rs +++ b/crunchy-cli-core/src/cli/utils.rs @@ -76,8 +76,55 @@ pub async fn download_segments( let thread_count = count.clone(); join_set.spawn(async move { for (i, segment) in thread_segments.into_iter().enumerate() { - let response = thread_client.get(&segment.url).send().await?; - let mut buf = response.bytes().await?.to_vec(); + let response_res = thread_client + .get(&segment.url) + .timeout(Duration::from_secs(60u64)) + .send() + .await; + let verfified_response = match response_res { + Ok(x) => x, + Err(y) => panic!("This is likely a netowrking error: {}", y), + }; + let possible_error_in_response = verfified_response.bytes().await; + let mut buf = if let Ok(r) = possible_error_in_response { + r.to_vec() + } else { + debug!( + "Segment Failed to download: {}, retrying.", + num + (i * cpus) + ); + let mut resp = thread_client + .get(&segment.url) + .timeout(Duration::from_secs(60u64)) + .send() + .await + .unwrap() + .bytes() + .await; + if resp.is_err() { + let mut retry_ctr = 1; + loop { + debug!( + "Segment Failed to download: {}, retry {}.", + num + (i * cpus), + retry_ctr + ); + resp = thread_client + .get(&segment.url) + .timeout(Duration::from_secs(60u64)) + .send() + .await + .unwrap() + .bytes() + .await; + if resp.is_ok() { + break; + } + retry_ctr += 1; + } + } + resp.unwrap().to_vec() + }; buf = VariantSegment::decrypt(buf.borrow_mut(), segment.key)?.to_vec(); debug!( From 8a3c0132e7e0ec4206d001670fd062bcf9673052 Mon Sep 17 00:00:00 2001 From: Alexandru Dracea Date: Wed, 28 Dec 2022 15:59:55 +0200 Subject: [PATCH 2/6] Update utils.rs --- crunchy-cli-core/src/cli/utils.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/cli/utils.rs b/crunchy-cli-core/src/cli/utils.rs index 3d14318..afc431f 100644 --- a/crunchy-cli-core/src/cli/utils.rs +++ b/crunchy-cli-core/src/cli/utils.rs @@ -3,7 +3,8 @@ use anyhow::{bail, Result}; use crunchyroll_rs::media::{Resolution, VariantData, VariantSegment}; use indicatif::{ProgressBar, ProgressFinish, ProgressStyle}; use log::{debug, LevelFilter}; -use std::borrow::{Borrow, BorrowMut}; +use std::borrow::Borrow; +use std::time::Duration; use std::collections::BTreeMap; use std::io::Write; use std::sync::{mpsc, Arc, Mutex}; From c2ae622d01c1913ff51264858a4c6b0f28353690 Mon Sep 17 00:00:00 2001 From: Alexandru Dracea Date: Wed, 28 Dec 2022 16:01:55 +0200 Subject: [PATCH 3/6] Update utils.rs --- crunchy-cli-core/src/cli/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/cli/utils.rs b/crunchy-cli-core/src/cli/utils.rs index afc431f..cd45859 100644 --- a/crunchy-cli-core/src/cli/utils.rs +++ b/crunchy-cli-core/src/cli/utils.rs @@ -3,7 +3,7 @@ use anyhow::{bail, Result}; use crunchyroll_rs::media::{Resolution, VariantData, VariantSegment}; use indicatif::{ProgressBar, ProgressFinish, ProgressStyle}; use log::{debug, LevelFilter}; -use std::borrow::Borrow; +use std::borrow::{Borrow, BorrowMut}; use std::time::Duration; use std::collections::BTreeMap; use std::io::Write; From d0681c7f6cc01caa684b39f30c459a20d5f09c24 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Wed, 28 Dec 2022 15:18:12 +0100 Subject: [PATCH 4/6] Simplify retry segment download --- crunchy-cli-core/src/cli/utils.rs | 62 ++++++++++--------------------- 1 file changed, 19 insertions(+), 43 deletions(-) diff --git a/crunchy-cli-core/src/cli/utils.rs b/crunchy-cli-core/src/cli/utils.rs index cd45859..7c32e86 100644 --- a/crunchy-cli-core/src/cli/utils.rs +++ b/crunchy-cli-core/src/cli/utils.rs @@ -4,10 +4,10 @@ use crunchyroll_rs::media::{Resolution, VariantData, VariantSegment}; use indicatif::{ProgressBar, ProgressFinish, ProgressStyle}; use log::{debug, LevelFilter}; use std::borrow::{Borrow, BorrowMut}; -use std::time::Duration; use std::collections::BTreeMap; use std::io::Write; use std::sync::{mpsc, Arc, Mutex}; +use std::time::Duration; use tokio::task::JoinSet; pub fn find_resolution( @@ -77,54 +77,30 @@ pub async fn download_segments( let thread_count = count.clone(); join_set.spawn(async move { for (i, segment) in thread_segments.into_iter().enumerate() { - let response_res = thread_client - .get(&segment.url) - .timeout(Duration::from_secs(60u64)) - .send() - .await; - let verfified_response = match response_res { - Ok(x) => x, - Err(y) => panic!("This is likely a netowrking error: {}", y), - }; - let possible_error_in_response = verfified_response.bytes().await; - let mut buf = if let Ok(r) = possible_error_in_response { - r.to_vec() - } else { - debug!( - "Segment Failed to download: {}, retrying.", - num + (i * cpus) - ); - let mut resp = thread_client + let mut retry_count = 0; + let mut buf = loop { + let response = thread_client .get(&segment.url) - .timeout(Duration::from_secs(60u64)) + .timeout(Duration::from_secs(10)) .send() .await - .unwrap() - .bytes() - .await; - if resp.is_err() { - let mut retry_ctr = 1; - loop { - debug!( - "Segment Failed to download: {}, retry {}.", - num + (i * cpus), - retry_ctr - ); - resp = thread_client - .get(&segment.url) - .timeout(Duration::from_secs(60u64)) - .send() - .await - .unwrap() - .bytes() - .await; - if resp.is_ok() { - break; + .unwrap(); + + match response.bytes().await { + Ok(b) => break b.to_vec(), + Err(e) => { + if e.is_body() { + if retry_count == 5 { + panic!("Max retry count reached ({}), multiple errors occured while receiving segment {}: {}", retry_count, num + (i * cpus), e) + } + debug!("Failed to download segment {}. Retrying ({} out of 5 retries left)", num + (i * cpus), 5 - retry_count) + } else { + panic!("{}", e) } - retry_ctr += 1; } } - resp.unwrap().to_vec() + + retry_count += 1; }; buf = VariantSegment::decrypt(buf.borrow_mut(), segment.key)?.to_vec(); From 7115c5546d1c71c496c26b82d85b2f1aaf114aca Mon Sep 17 00:00:00 2001 From: ByteDream Date: Wed, 28 Dec 2022 15:25:10 +0100 Subject: [PATCH 5/6] Show error message on segment download retry --- crunchy-cli-core/src/cli/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/cli/utils.rs b/crunchy-cli-core/src/cli/utils.rs index 7c32e86..e2bbc63 100644 --- a/crunchy-cli-core/src/cli/utils.rs +++ b/crunchy-cli-core/src/cli/utils.rs @@ -93,7 +93,7 @@ pub async fn download_segments( if retry_count == 5 { panic!("Max retry count reached ({}), multiple errors occured while receiving segment {}: {}", retry_count, num + (i * cpus), e) } - debug!("Failed to download segment {}. Retrying ({} out of 5 retries left)", num + (i * cpus), 5 - retry_count) + debug!("Failed to download segment {} ({}). Retrying, {} out of 5 retries left", num + (i * cpus), e, 5 - retry_count) } else { panic!("{}", e) } From b8e46099f9035c609b376c2cfa1b0d28719564c9 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Wed, 28 Dec 2022 15:35:38 +0100 Subject: [PATCH 6/6] Re-increase segment request timeout --- crunchy-cli-core/src/cli/utils.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/cli/utils.rs b/crunchy-cli-core/src/cli/utils.rs index e2bbc63..841dbef 100644 --- a/crunchy-cli-core/src/cli/utils.rs +++ b/crunchy-cli-core/src/cli/utils.rs @@ -81,7 +81,7 @@ pub async fn download_segments( let mut buf = loop { let response = thread_client .get(&segment.url) - .timeout(Duration::from_secs(10)) + .timeout(Duration::from_secs(60)) .send() .await .unwrap();