Commit 17b53943be2d
tarball2 files changed+43-27
@@ -227,7 +227,11 @@ pub struct AttachmentConfig {
227227
}228228
229229
impl Timeline {230
- #[doc = "Wait until this live timeline has applied all history currently retained by its room cache."]230
+ /// Wait for earlier history operations on the room cache, then until this231
+ /// live timeline has applied every update they published.232
+ ///233
+ /// Updates apply incrementally, keeping read receipts and item ids, and234
+ /// only a lagged subscriber falls back to replacing the timeline.231235
pub async fn flush_history(&self) -> Result<(), Error> {232236
let Some(flush) = &self.history_flush else {233237
return Ok(());@@ -25,7 +25,10 @@ use matrix_sdk::{
2525
send_queue::RoomSendQueueUpdate,2626
};2727
use ruma::OwnedEventId;28
-use tokio::sync::broadcast::{Receiver, error::RecvError};28
+use tokio::sync::broadcast::{29
+ Receiver,30
+ error::{RecvError, TryRecvError},31
+};2932
use tokio::sync::{mpsc, oneshot};3033
use tracing::{error, instrument, trace, warn};3134
@@ -213,39 +216,48 @@ pub(in crate::timeline) async fn room_event_cache_updates_task(
213216
) {214217
trace!("Spawned the event subscriber task.");215218
219
+ let mut flushing: Option<oneshot::Sender<Result<(), crate::timeline::Error>>> = None;220
+216221
loop {217222
trace!("Waiting for an event.");218223
219
- let update = tokio::select! {220
- request = async {221
- match history_flush_requests.as_mut() {222
- Some(requests) => requests.recv().await,223
- None => std::future::pending::<Option<oneshot::Sender<Result<(), crate::timeline::Error>>>>().await,224
+ let update = if let Some(reply) = flushing.take() {225
+ match room_event_cache_subscriber.try_recv() {226
+ Ok(update) => {227
+ flushing = Some(reply);228
+ Ok(update)229
+ }230
+ Err(TryRecvError::Empty) => {231
+ let _ = reply.send(Ok(()));232
+ continue;224233
}225
- } => {226
- if let Some(reply) = request {227
- if let Err(error) = room_event_cache.wait_for_history().await {228
- let _ = reply.send(Err(error.into()));229
- continue;234
+ Err(TryRecvError::Lagged(num_skipped)) => {235
+ flushing = Some(reply);236
+ Err(RecvError::Lagged(num_skipped))237
+ }238
+ Err(TryRecvError::Closed) => break,239
+ }240
+ } else {241
+ tokio::select! {242
+ request = async {243
+ match history_flush_requests.as_mut() {244
+ Some(requests) => requests.recv().await,245
+ None => std::future::pending().await,230246
}231
- match room_event_cache.subscribe_with_history().await {232
- Ok((initial_events, gaps, subscriber)) => {233
- room_event_cache_subscriber = subscriber;234
- timeline_controller235
- .replace_with_initial_history(initial_events, gaps, RemoteEventOrigin::Cache)236
- .await;237
- let _ = reply.send(Ok(()));238
- }239
- Err(error) => {240
- let _ = reply.send(Err(error.into()));241
- }247
+ } => {248
+ match request {249
+ Some(reply) => match room_event_cache.wait_for_history().await {250
+ Ok(()) => flushing = Some(reply),251
+ Err(error) => {252
+ let _ = reply.send(Err(error.into()));253
+ }254
+ },255
+ None => history_flush_requests = None,242256
}243
- } else {244
- history_flush_requests = None;257
+ continue;245258
}246
- continue;259
+ update = room_event_cache_subscriber.recv() => update,247260
}248
- update = room_event_cache_subscriber.recv() => update,249261
};250262
let update = match update {251263
Ok(up) => up,