diff --git a/src/api/client/sync/v3.rs b/src/api/client/sync/v3.rs index 406b497dc..edb2b9452 100644 --- a/src/api/client/sync/v3.rs +++ b/src/api/client/sync/v3.rs @@ -124,6 +124,33 @@ pub(crate) async fn sync_events_route( // Setup watchers, so if there's no response, we can wait for them let watcher = services.sync.watch(sender_user, sender_device); + let response = build_sync_events(services, &body).await?; + if body.body.full_state + || !(response.rooms.is_empty() + && response.presence.is_empty() + && response.account_data.is_empty() + && response.device_lists.is_empty() + && response.to_device.is_empty()) + { + return Ok(response); + } + + // Hang a few seconds so requests are not spammed + // Stop hanging if new info arrives + let default = Duration::from_secs(30); + let duration = cmp::min(body.body.timeout.unwrap_or(default), default); + _ = tokio::time::timeout(duration, watcher).await; + + // Retry returning data + build_sync_events(services, &body).await +} + +pub(crate) async fn build_sync_events( + services: crate::State, + body: &Ruma, +) -> Result> { + let (sender_user, sender_device) = body.sender(); + let next_batch = services.globals.current_count()?; let next_batch_string = next_batch.to_string(); @@ -327,21 +354,6 @@ pub(crate) async fn sync_events_route( to_device: ToDevice { events: to_device_events }, }; - // TODO: Retry the endpoint instead of returning - if !full_state - && response.rooms.is_empty() - && response.presence.is_empty() - && response.account_data.is_empty() - && response.device_lists.is_empty() - && response.to_device.is_empty() - { - // Hang a few seconds so requests are not spammed - // Stop hanging if new info arrives - let default = Duration::from_secs(30); - let duration = cmp::min(body.body.timeout.unwrap_or(default), default); - _ = tokio::time::timeout(duration, watcher).await; - } - Ok(response) }