feat(sdk): Add RoomEventCache::events to avoid ::subscribe.
`RoomEventCache::subscribe` returns the set of events + the `RoomEventCacheListener`. However, creating this listener isn't cheap, especially dropping it. That's why this patch creates `RoomEventCache::events` to replace `subscribe` when the listener is not necessary.
This commit is contained in:
@@ -351,7 +351,7 @@ async fn room_event_cache_updates_task(
|
||||
// The updates might have lagged, but the room event cache might have
|
||||
// events, so retrieve them and add them back again to the timeline,
|
||||
// after clearing it.
|
||||
let (initial_events, _stream) = room_event_cache.subscribe().await;
|
||||
let initial_events = room_event_cache.events().await;
|
||||
|
||||
timeline_controller
|
||||
.replace_with_initial_remote_events(
|
||||
|
||||
@@ -345,7 +345,7 @@ impl<P: RoomDataProvider, D: Decryptor> TimelineController<P, D> {
|
||||
match &*focus_guard {
|
||||
TimelineFocusData::Live => {
|
||||
// Retrieve the cached events, and add them to the timeline.
|
||||
let (events, _stream) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
|
||||
let has_events = !events.is_empty();
|
||||
|
||||
|
||||
@@ -158,8 +158,22 @@ impl RoomEventCache {
|
||||
}
|
||||
}
|
||||
|
||||
/// Read all current events.
|
||||
///
|
||||
/// Use [`RoomEventCache::subscribe`] to get all current events, plus a
|
||||
/// listener/subscriber.
|
||||
pub async fn events(&self) -> Vec<TimelineEvent> {
|
||||
let state = self.inner.state.read().await;
|
||||
|
||||
state.events().events().map(|(_position, item)| item.clone()).collect()
|
||||
}
|
||||
|
||||
/// Subscribe to this room updates, after getting the initial list of
|
||||
/// events.
|
||||
///
|
||||
/// Use [`RoomEventCache::events`] to get all current events without the
|
||||
/// listener/subscriber. Creating, and especially dropping, a
|
||||
/// [`RoomEventCacheListener`] isn't free.
|
||||
pub async fn subscribe(&self) -> (Vec<TimelineEvent>, RoomEventCacheListener) {
|
||||
let state = self.inner.state.read().await;
|
||||
let events = state.events().events().map(|(_position, item)| item.clone()).collect();
|
||||
@@ -1637,7 +1651,7 @@ mod tests {
|
||||
|
||||
// The in-memory linked chunk keeps the bundled relation.
|
||||
{
|
||||
let (events, _) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
|
||||
assert_eq!(events.len(), 1);
|
||||
|
||||
@@ -1803,7 +1817,7 @@ mod tests {
|
||||
assert!(room_event_cache.event(event_id1).await.is_some());
|
||||
|
||||
// But their presence in a linked chunk is forgotten.
|
||||
let (items, _) = room_event_cache.subscribe().await;
|
||||
let items = room_event_cache.events().await;
|
||||
assert!(items.is_empty());
|
||||
|
||||
// The event cache store too.
|
||||
@@ -1935,7 +1949,7 @@ mod tests {
|
||||
// when subscribing, to check that the items correspond to their new
|
||||
// positions. The duplicated item is removed (so it's not the first
|
||||
// element anymore), and it's added to the back of the list.
|
||||
let (items, _stream) = room_event_cache.subscribe().await;
|
||||
let items = room_event_cache.events().await;
|
||||
assert_eq!(items.len(), 2);
|
||||
assert_eq!(items[0].event_id().unwrap(), event_id1);
|
||||
assert_eq!(items[1].event_id().unwrap(), event_id2);
|
||||
@@ -1995,7 +2009,7 @@ mod tests {
|
||||
|
||||
let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap();
|
||||
|
||||
let (items, _stream) = room_event_cache.subscribe().await;
|
||||
let items = room_event_cache.events().await;
|
||||
|
||||
// Because the persisted content was invalid, the room store is reset: there are
|
||||
// no events in the cache.
|
||||
@@ -2262,7 +2276,7 @@ mod tests {
|
||||
assert!(stream.is_empty());
|
||||
|
||||
// When reading the events, we do get only the last one.
|
||||
let (events, _) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
assert_eq!(events.len(), 1);
|
||||
assert_eq!(events[0].event_id().as_deref(), Some(evid2));
|
||||
|
||||
@@ -2386,7 +2400,7 @@ mod tests {
|
||||
}
|
||||
|
||||
// Getting the events will only give us the latest chunk.
|
||||
let (events3, _stream2) = room_event_cache.subscribe().await;
|
||||
let events3 = room_event_cache.events().await;
|
||||
assert_eq!(events3.len(), 1);
|
||||
assert_eq!(events3[0].event_id().as_deref(), Some(evid2));
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ async fn test_ignored_unignored() {
|
||||
{
|
||||
let room = client.get_room(other_room_id).unwrap();
|
||||
let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap();
|
||||
let (events, _) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
assert!(events.is_empty());
|
||||
}
|
||||
|
||||
@@ -984,7 +984,7 @@ async fn test_backpaginate_with_no_initial_events() {
|
||||
pagination.run_backwards_once(20).await.unwrap();
|
||||
|
||||
// The linked chunk should contain the events in the correct order.
|
||||
let (events, _stream) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
|
||||
assert_eq!(events.len(), 3, "{events:?}");
|
||||
assert_event_matches_msg(&events[0], "oh well");
|
||||
@@ -1047,7 +1047,7 @@ async fn test_backpaginate_replace_empty_gap() {
|
||||
pagination.run_backwards_once(20).await.unwrap();
|
||||
|
||||
// The linked chunk should contain the events in the correct order.
|
||||
let (events, _stream) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
|
||||
assert_event_matches_msg(&events[0], "hello");
|
||||
assert_event_matches_msg(&events[1], "world");
|
||||
@@ -1130,7 +1130,7 @@ async fn test_no_gap_stored_after_deduplicated_sync() {
|
||||
assert!(stream.is_empty());
|
||||
|
||||
{
|
||||
let (events, _) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
assert_event_matches_msg(&events[0], "hello");
|
||||
assert_event_matches_msg(&events[1], "world");
|
||||
assert_event_matches_msg(&events[2], "sup");
|
||||
@@ -1149,7 +1149,7 @@ async fn test_no_gap_stored_after_deduplicated_sync() {
|
||||
assert!(outcome.reached_start);
|
||||
|
||||
{
|
||||
let (events, _) = room_event_cache.subscribe().await;
|
||||
let events = room_event_cache.events().await;
|
||||
assert_event_matches_msg(&events[0], "hello");
|
||||
assert_event_matches_msg(&events[1], "world");
|
||||
assert_event_matches_msg(&events[2], "sup");
|
||||
|
||||
@@ -28,8 +28,7 @@ impl Widget for &mut EventsView<'_> {
|
||||
let events = tokio::task::block_in_place(|| {
|
||||
Handle::current().block_on(async {
|
||||
let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap();
|
||||
let (events, _) = room_event_cache.subscribe().await;
|
||||
events
|
||||
room_event_cache.events().await
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user