diff --git a/api_tests/src/post.spec.ts b/api_tests/src/post.spec.ts index 1696ef998..b2d07c291 100644 --- a/api_tests/src/post.spec.ts +++ b/api_tests/src/post.spec.ts @@ -279,8 +279,9 @@ test("Delete a post", async () => { // Make sure lemmy beta sees post is deleted // This will be undefined because of the tombstone - await expect(resolvePost(beta, postRes.post_view.post)).rejects.toBe( - "couldnt_find_object", + await waitUntil( + () => resolvePost(beta, postRes.post_view.post).catch(e => e), + e => e === "couldnt_find_object", ); // Undelete @@ -288,7 +289,12 @@ test("Delete a post", async () => { expect(undeletedPost.post_view.post.deleted).toBe(false); // Make sure lemmy beta sees post is undeleted - let betaPost2 = (await resolvePost(beta, postRes.post_view.post)).post; + let betaPost2 = ( + await waitUntil( + () => resolvePost(beta, postRes.post_view.post).catch(e => e), + e => e !== "couldnt_find_object", + ) + ).post; if (!betaPost2) { throw "Missing beta post 2"; } diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts index 7e6124025..6898221f3 100644 --- a/api_tests/src/shared.ts +++ b/api_tests/src/shared.ts @@ -872,13 +872,15 @@ export async function waitUntil( fetcher: () => Promise, checker: (t: T) => boolean, retries = 10, - delaySeconds = 2, + delaySeconds = [0.2, 0.5, 1, 2, 3], ) { let retry = 0; while (retry++ < retries) { const result = await fetcher(); if (checker(result)) return result; - await delay(delaySeconds * 1000); + await delay( + delaySeconds[Math.min(retry - 1, delaySeconds.length - 1)] * 1000, + ); } throw Error( `Failed "${fetcher}": "${checker}" did not return true after ${retries} retries (delayed ${delaySeconds}s each)`, diff --git a/crates/federate/src/util.rs b/crates/federate/src/util.rs index 4f260708d..f00ccadb3 100644 --- a/crates/federate/src/util.rs +++ b/crates/federate/src/util.rs @@ -31,6 +31,26 @@ use std::{ use tokio::{task::JoinHandle, time::sleep}; use tokio_util::sync::CancellationToken; +/// Decrease the delays of the federation queue. +/// Should only be used for federation tests since it significantly increases CPU and DB load of the federation queue. +pub(crate) static LEMMY_TEST_FAST_FEDERATION: Lazy = Lazy::new(|| { + std::env::var("LEMMY_TEST_FAST_FEDERATION") + .map(|s| !s.is_empty()) + .unwrap_or(false) +}); +/// Recheck for new federation work every n seconds. +/// +/// When the queue is processed faster than new activities are added and it reaches the current time with an empty batch, +/// this is the delay the queue waits before it checks if new activities have been added to the sent_activities table. +/// This delay is only applied if no federated activity happens during sending activities of the last batch. +pub(crate) static WORK_FINISHED_RECHECK_DELAY: Lazy = Lazy::new(|| { + if *LEMMY_TEST_FAST_FEDERATION { + Duration::from_millis(100) + } else { + Duration::from_secs(30) + } +}); + pub struct CancellableTask { f: Pin> + Send + 'static>>, ended: Arc>, @@ -162,7 +182,11 @@ pub(crate) async fn get_activity_cached( pub(crate) async fn get_latest_activity_id(pool: &mut DbPool<'_>) -> Result { static CACHE: Lazy> = Lazy::new(|| { Cache::builder() - .time_to_live(Duration::from_secs(1)) + .time_to_live(if *LEMMY_TEST_FAST_FEDERATION { + *WORK_FINISHED_RECHECK_DELAY + } else { + Duration::from_secs(1) + }) .build() }); CACHE diff --git a/crates/federate/src/worker.rs b/crates/federate/src/worker.rs index b52e4dbbf..b6e174c04 100644 --- a/crates/federate/src/worker.rs +++ b/crates/federate/src/worker.rs @@ -1,6 +1,13 @@ use crate::{ federation_queue_state::FederationQueueState, - util::{get_activity_cached, get_actor_cached, get_latest_activity_id, retry_sleep_duration}, + util::{ + get_activity_cached, + get_actor_cached, + get_latest_activity_id, + retry_sleep_duration, + LEMMY_TEST_FAST_FEDERATION, + WORK_FINISHED_RECHECK_DELAY, + }, }; use activitypub_federation::{activity_sending::SendActivityTask, config::Data}; use anyhow::{Context, Result}; @@ -23,31 +30,11 @@ use std::{ use tokio::{sync::mpsc::UnboundedSender, time::sleep}; use tokio_util::sync::CancellationToken; -/// Decrease the delays of the federation queue. -/// Should only be used for federation tests since it significantly increases CPU and DB load of the federation queue. -static LEMMY_TEST_FAST_FEDERATION: Lazy = Lazy::new(|| { - std::env::var("LEMMY_TEST_FAST_FEDERATION") - .map(|s| !s.is_empty()) - .unwrap_or(false) -}); - /// Check whether to save state to db every n sends if there's no failures (during failures state is saved after every attempt) /// This determines the batch size for loop_batch. After a batch ends and SAVE_STATE_EVERY_TIME has passed, the federation_queue_state is updated in the DB. static CHECK_SAVE_STATE_EVERY_IT: i64 = 100; /// Save state to db after this time has passed since the last state (so if the server crashes or is SIGKILLed, less than X seconds of activities are resent) static SAVE_STATE_EVERY_TIME: Duration = Duration::from_secs(60); -/// Recheck for new federation work every n seconds. -/// -/// When the queue is processed faster than new activities are added and it reaches the current time with an empty batch, -/// this is the delay the queue waits before it checks if new activities have been added to the sent_activities table. -/// This delay is only applied if no federated activity happens during sending activities of the last batch. -static WORK_FINISHED_RECHECK_DELAY: Lazy = Lazy::new(|| { - if *LEMMY_TEST_FAST_FEDERATION { - Duration::from_secs(1) - } else { - Duration::from_secs(30) - } -}); /// interval with which new additions to community_followers are queried. /// /// The first time some user on an instance follows a specific remote community (or, more precisely: the first time a (followed_community_id, follower_inbox_url) tuple appears),