diff --git a/libs/client-api/src/native/http_native.rs b/libs/client-api/src/native/http_native.rs index 18b4ea44..8ab165b0 100644 --- a/libs/client-api/src/native/http_native.rs +++ b/libs/client-api/src/native/http_native.rs @@ -25,10 +25,11 @@ use std::future::Future; use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC}; use std::pin::Pin; use std::sync::atomic::Ordering; + use std::task::{Context, Poll}; use std::time::Duration; use tokio_retry::strategy::{ExponentialBackoff, FixedInterval}; -use tokio_retry::{Retry, RetryIf}; +use tokio_retry::{Condition, RetryIf}; use tracing::{event, info, instrument, trace}; pub use infra::file_util::ChunkedBytes; @@ -138,7 +139,7 @@ impl Client { // 2 seconds, 4 seconds, 8 seconds let retry_strategy = ExponentialBackoff::from_millis(2).factor(1000).take(3); let action = GetCollabAction::new(self.clone(), params); - Retry::spawn(retry_strategy, action).await + RetryIf::spawn(retry_strategy, action, RetryGetCollabCondition).await } #[instrument(level = "debug", skip_all, err)] @@ -391,3 +392,10 @@ where Ok(Bytes::from(chunk)) } + +struct RetryGetCollabCondition; +impl Condition for RetryGetCollabCondition { + fn should_retry(&mut self, error: &AppResponseError) -> bool { + !error.is_record_not_found() + } +} diff --git a/services/appflowy-collaborate/src/collab/disk_cache.rs b/services/appflowy-collaborate/src/collab/disk_cache.rs index a3d21d88..916d9da0 100644 --- a/services/appflowy-collaborate/src/collab/disk_cache.rs +++ b/services/appflowy-collaborate/src/collab/disk_cache.rs @@ -4,7 +4,7 @@ use std::time::Duration; use anyhow::anyhow; use collab::entity::EncodedCollab; use collab_entity::CollabType; -use sqlx::{PgPool, Transaction}; +use sqlx::{Error, PgPool, Transaction}; use tokio::time::sleep; use tracing::{event, instrument, Level}; use uuid::Uuid; @@ -100,19 +100,21 @@ impl CollabDiskCache { .await?; }, Err(e) => { - // Handle non-retryable errors immediately - if matches!(e, sqlx::Error::RowNotFound) { - let msg = format!("Can't find the row for query: {:?}", query); - return Err(AppError::RecordNotFound(msg)); - } - - // Increment attempts and retry if below MAX_ATTEMPTS and the error is retryable - if attempts < MAX_ATTEMPTS - 1 && matches!(e, sqlx::Error::PoolTimedOut) { - attempts += 1; - sleep(Duration::from_millis(500 * attempts as u64)).await; - continue; - } else { - return Err(e.into()); + match e { + Error::RowNotFound => { + let msg = format!("Can't find the row for query: {:?}", query); + return Err(AppError::RecordNotFound(msg)); + }, + _ => { + // Increment attempts and retry if below MAX_ATTEMPTS and the error is retryable + if attempts < MAX_ATTEMPTS - 1 && matches!(e, sqlx::Error::PoolTimedOut) { + attempts += 1; + sleep(Duration::from_millis(500 * attempts as u64)).await; + continue; + } else { + return Err(e.into()); + } + }, } }, }