Skip to content

Commit 39a9f96

Browse files
committed
feat(sdk): Add SlidingSyncListBuilder::requires_timeout.
This patch adds a new `SlidingSyncListBuilder::requires_timeout` method that takes a function deciding whether the list requires a timeout, i.e. if the list should trigger a `http::Request::timeout`, i.e. if it deserves a long-polling or not. The default behaviour is kept for compatibility purposes.
1 parent e971fb7 commit 39a9f96

File tree

3 files changed

+72
-25
lines changed

3 files changed

+72
-25
lines changed

crates/matrix-sdk/src/sliding_sync/list/builder.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ struct SlidingSyncListCachedData {
3333
#[derive(Clone)]
3434
pub struct SlidingSyncListBuilder {
3535
sync_mode: SlidingSyncMode,
36+
#[cfg(not(target_family = "wasm"))]
37+
requires_timeout: Arc<dyn Fn(&SlidingSyncListRequestGenerator) -> bool + Send + Sync>,
38+
#[cfg(target_family = "wasm")]
39+
requires_timeout: Arc<dyn Fn(&SlidingSyncListRequestGenerator) -> bool>,
3640
required_state: Vec<(StateEventType, String)>,
3741
filters: Option<http::request::ListFilters>,
3842
timeline_limit: Bound,
@@ -70,6 +74,7 @@ impl SlidingSyncListBuilder {
7074
pub(super) fn new(name: impl Into<String>) -> Self {
7175
Self {
7276
sync_mode: SlidingSyncMode::default(),
77+
requires_timeout: Arc::new(|request_generator| request_generator.is_fully_loaded()),
7378
required_state: vec![
7479
(StateEventType::RoomEncryption, "".to_owned()),
7580
(StateEventType::RoomTombstone, "".to_owned()),
@@ -117,6 +122,34 @@ impl SlidingSyncListBuilder {
117122
self
118123
}
119124

125+
/// Custom function to decide whether this list requires a
126+
/// [`http::Request::timeout`] value.
127+
///
128+
/// A list requires a `timeout` query if and only if we want the server to
129+
/// wait on new updates, i.e. to do a long-polling.
130+
#[cfg(not(target_family = "wasm"))]
131+
pub fn requires_timeout<F>(mut self, f: F) -> Self
132+
where
133+
F: Fn(&SlidingSyncListRequestGenerator) -> bool + Send + Sync + 'static,
134+
{
135+
self.requires_timeout = Arc::new(f);
136+
self
137+
}
138+
139+
/// Custom function to decide whether this list requires a
140+
/// [`http::Request::timeout`] value.
141+
///
142+
/// A list requires a `timeout` query if and only if we want the server to
143+
/// wait on new updates, i.e. to do a long-polling.
144+
#[cfg(target_family = "wasm")]
145+
pub fn requires_timeout<F>(mut self, f: F) -> Self
146+
where
147+
F: Fn(&SlidingSyncListRequestGenerator) -> bool + 'static,
148+
{
149+
self.requires_timeout = Arc::new(f);
150+
self
151+
}
152+
120153
/// Required states to return per room.
121154
pub fn required_state(mut self, value: Vec<(StateEventType, String)>) -> Self {
122155
self.required_state = value;
@@ -186,6 +219,7 @@ impl SlidingSyncListBuilder {
186219
timeline_limit: StdRwLock::new(self.timeline_limit),
187220
name: self.name,
188221
cache_policy: self.cache_policy,
222+
requires_timeout: self.requires_timeout,
189223

190224
// Computed from the builder.
191225
request_generator: StdRwLock::new(SlidingSyncListRequestGenerator::new(

crates/matrix-sdk/src/sliding_sync/list/mod.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod request_generator;
44
mod sticky;
55

66
use std::{
7-
fmt::Debug,
7+
fmt,
88
ops::RangeInclusive,
99
sync::{Arc, RwLock as StdRwLock},
1010
};
@@ -95,18 +95,11 @@ impl SlidingSyncList {
9595
/// Check whether this list requires a [`http::Request::timeout`] value.
9696
///
9797
/// A list requires a `timeout` query if and only if we want the server to
98-
/// wait on new updates, i.e. to do a long-polling. If the list has a
99-
/// selective sync mode ([`SlidingSyncMode::Selective`]), we expect the
100-
/// server to always wait for new updates as the list ranges are always
101-
/// the same. Otherwise, if the list is fully loaded, it means the list
102-
/// ranges cover all the available rooms, then we expect the server
103-
/// to always wait for new updates. If the list isn't fully loaded, it
104-
/// means the current list ranges may hit a set of rooms that have no
105-
/// update, but we don't want to wait for updates; we instead want to
106-
/// move quickly to the next range.
98+
/// wait on new updates, i.e. to do a long-polling.
10799
pub(super) fn requires_timeout(&self) -> bool {
108-
self.inner.request_generator.read().unwrap().is_selective()
109-
|| self.state().is_fully_loaded()
100+
let request_generator = &*self.inner.request_generator.read().unwrap();
101+
102+
(self.inner.requires_timeout)(request_generator)
110103
}
111104

112105
/// Get a stream of state updates.
@@ -211,14 +204,19 @@ impl SlidingSyncList {
211204
}
212205
}
213206

214-
#[derive(Debug)]
215207
pub(super) struct SlidingSyncListInner {
216208
/// Name of this list to easily recognize them.
217209
name: String,
218210

219211
/// The state this list is in.
220212
state: SharedObservable<SlidingSyncListLoadingState>,
221213

214+
/// Does this list require a timeout?
215+
#[cfg(not(target_family = "wasm"))]
216+
requires_timeout: Arc<dyn Fn(&SlidingSyncListRequestGenerator) -> bool + Send + Sync>,
217+
#[cfg(target_family = "wasm")]
218+
requires_timeout: Arc<dyn Fn(&SlidingSyncListRequestGenerator) -> bool>,
219+
222220
/// Parameters that are sticky, and can be sent only once per session (until
223221
/// the connection is dropped or the server invalidates what the client
224222
/// knows).
@@ -251,6 +249,15 @@ pub(super) struct SlidingSyncListInner {
251249
sync_mode: StdRwLock<SlidingSyncMode>,
252250
}
253251

252+
impl fmt::Debug for SlidingSyncListInner {
253+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254+
f.debug_struct("SlidingSyncListInner")
255+
.field("name", &self.name)
256+
.field("state", &self.state)
257+
.finish()
258+
}
259+
}
260+
254261
impl SlidingSyncListInner {
255262
/// Change the sync-mode.
256263
///
@@ -374,6 +381,7 @@ pub enum SlidingSyncListLoadingState {
374381
FullyLoaded,
375382
}
376383

384+
#[cfg(test)]
377385
impl SlidingSyncListLoadingState {
378386
/// Check whether the state is [`Self::FullyLoaded`].
379387
fn is_fully_loaded(&self) -> bool {

crates/matrix-sdk/src/sliding_sync/list/request_generator.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::{SlidingSyncListLoadingState, sliding_sync::Error};
3535

3636
/// The kind of request generator.
3737
#[derive(Debug, PartialEq)]
38-
pub(super) enum SlidingSyncListRequestGeneratorKind {
38+
pub enum SlidingSyncListRequestGeneratorKind {
3939
/// Growing-mode (see [`SlidingSyncMode`]).
4040
Growing {
4141
/// Size of the batch, used to grow the range to fetch more rooms.
@@ -72,7 +72,7 @@ pub(super) enum SlidingSyncListRequestGeneratorKind {
7272

7373
/// A request generator for [`SlidingSyncList`].
7474
#[derive(Debug)]
75-
pub(in super::super) struct SlidingSyncListRequestGenerator {
75+
pub struct SlidingSyncListRequestGenerator {
7676
/// The current ranges used by this request generator.
7777
///
7878
/// Note there's only one range in the `Growing` and `Paging` mode.
@@ -114,22 +114,20 @@ impl SlidingSyncListRequestGenerator {
114114
}
115115
}
116116

117-
/// Check whether this request generator is of kind
118-
/// [`SlidingSyncListRequestGeneratorKind::Selective`].
119-
pub(super) fn is_selective(&self) -> bool {
120-
matches!(self.kind, SlidingSyncListRequestGeneratorKind::Selective)
121-
}
122-
123117
/// Return a view on the ranges requested by this generator.
124118
///
125119
/// For generators in the selective mode, this is the initial set of ranges.
126120
/// For growing and paginated generators, this is the range committed in the
127121
/// latest response received from the server.
128-
#[cfg(test)]
129-
pub(super) fn requested_ranges(&self) -> &[Range] {
122+
pub fn requested_ranges(&self) -> &[Range] {
130123
&self.ranges
131124
}
132125

126+
/// Return the kind of request generator is used by this generator.
127+
pub fn kind(&self) -> &SlidingSyncListRequestGeneratorKind {
128+
&self.kind
129+
}
130+
133131
/// Update internal state of the generator (namely, ranges) before the next
134132
/// sliding sync request.
135133
pub(super) fn generate_next_ranges(
@@ -280,14 +278,21 @@ impl SlidingSyncListRequestGenerator {
280278
}
281279
}
282280

283-
#[cfg(test)]
284-
pub(super) fn is_fully_loaded(&self) -> bool {
281+
/// Check whether the list is fully loaded.
282+
pub fn is_fully_loaded(&self) -> bool {
285283
match self.kind {
286284
SlidingSyncListRequestGeneratorKind::Paging { fully_loaded, .. }
287285
| SlidingSyncListRequestGeneratorKind::Growing { fully_loaded, .. } => fully_loaded,
288286
SlidingSyncListRequestGeneratorKind::Selective => true,
289287
}
290288
}
289+
290+
/// Check whether this request generator is of kind
291+
/// [`SlidingSyncListRequestGeneratorKind::Selective`].
292+
#[cfg(test)]
293+
pub fn is_selective(&self) -> bool {
294+
matches!(self.kind, SlidingSyncListRequestGeneratorKind::Selective)
295+
}
291296
}
292297

293298
fn create_range(

0 commit comments

Comments
 (0)