Skip to content

Commit 6c0afae

Browse files
committed
Merge remote-tracking branch 'origin/main' into release-matrix-sdk-crypto-js-0.1.0-alpha.9
2 parents 89bf7f2 + 923d425 commit 6c0afae

File tree

12 files changed

+554
-122
lines changed

12 files changed

+554
-122
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmarks/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ publish = false
99

1010
[dependencies]
1111
criterion = { version = "0.4.0", features = ["async", "async_tokio", "html_reports"] }
12+
matrix-sdk-base = { path = "../crates/matrix-sdk-base" }
1213
matrix-sdk-crypto = { path = "../crates/matrix-sdk-crypto", version = "0.6.0"}
1314
matrix-sdk-sqlite = { path = "../crates/matrix-sdk-sqlite", version = "0.1.0", default-features = false, features = ["crypto-store"] }
14-
matrix-sdk-sled = { path = "../crates/matrix-sdk-sled", version = "0.2.0", default-features = false, features = ["crypto-store"] }
15+
matrix-sdk-sled = { path = "../crates/matrix-sdk-sled", version = "0.2.0", features = ["crypto-store"] }
1516
matrix-sdk-test = { path = "../testing/matrix-sdk-test", version = "0.6.0"}
17+
matrix-sdk = { path = "../crates/matrix-sdk" }
1618
ruma = { workspace = true }
1719
serde_json = { workspace = true }
1820
tempfile = "3.3.0"
@@ -24,3 +26,7 @@ pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
2426
[[bench]]
2527
name = "crypto_bench"
2628
harness = false
29+
30+
[[bench]]
31+
name = "store_bench"
32+
harness = false

benchmarks/benches/store_bench.rs

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
use criterion::*;
2+
use matrix_sdk::{config::StoreConfig, Client, RoomInfo, RoomState, Session, StateChanges};
3+
use matrix_sdk_base::{store::MemoryStore, StateStore as _};
4+
use matrix_sdk_sled::SledStateStore;
5+
use matrix_sdk_sqlite::SqliteStateStore;
6+
use ruma::{device_id, user_id, RoomId};
7+
use tokio::runtime::Builder;
8+
9+
fn criterion() -> Criterion {
10+
#[cfg(target_os = "linux")]
11+
let criterion = Criterion::default().with_profiler(pprof::criterion::PProfProfiler::new(
12+
100,
13+
pprof::criterion::Output::Flamegraph(None),
14+
));
15+
16+
#[cfg(not(target_os = "linux"))]
17+
let criterion = Criterion::default();
18+
19+
criterion
20+
}
21+
22+
/// Number of joined rooms in the benchmark.
23+
const NUM_JOINED_ROOMS: usize = 10000;
24+
25+
/// Number of stripped rooms in the benchmark.
26+
const NUM_STRIPPED_JOINED_ROOMS: usize = 10000;
27+
28+
pub fn restore_session(c: &mut Criterion) {
29+
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");
30+
31+
// Create a fake list of changes, and a session to recover from.
32+
let mut changes = StateChanges::default();
33+
34+
for i in 0..NUM_JOINED_ROOMS {
35+
let room_id = RoomId::parse(format!("!room{i}:example.com")).unwrap().to_owned();
36+
changes.add_room(RoomInfo::new(&room_id, RoomState::Joined));
37+
}
38+
39+
for i in 0..NUM_STRIPPED_JOINED_ROOMS {
40+
let room_id = RoomId::parse(format!("!strippedroom{i}:example.com")).unwrap().to_owned();
41+
changes.add_stripped_room(RoomInfo::new(&room_id, RoomState::Joined));
42+
}
43+
44+
let session = Session {
45+
access_token: "OHEY".to_owned(),
46+
refresh_token: None,
47+
user_id: user_id!("@somebody:example.com").to_owned(),
48+
device_id: device_id!("DEVICE_ID").to_owned(),
49+
};
50+
51+
// Start the benchmark.
52+
53+
let mut group = c.benchmark_group("Client reload");
54+
group.throughput(Throughput::Elements(100));
55+
56+
const NAME: &str = "restore a session";
57+
58+
// Memory
59+
let mem_store = MemoryStore::new();
60+
runtime.block_on(mem_store.save_changes(&changes)).expect("initial filling of mem failed");
61+
62+
group.bench_with_input(BenchmarkId::new("memory store", NAME), &mem_store, |b, store| {
63+
b.to_async(&runtime).iter(|| async {
64+
let client = Client::builder()
65+
.homeserver_url("https://matrix.example.com")
66+
.store_config(StoreConfig::new().state_store(store.clone()))
67+
.build()
68+
.await
69+
.expect("Can't build client");
70+
client.restore_session(session.clone()).await.expect("couldn't restore session");
71+
})
72+
});
73+
74+
for encryption_password in [None, Some("hunter2")] {
75+
let encrypted_suffix = if encryption_password.is_some() { "encrypted" } else { "clear" };
76+
77+
// Sled
78+
let sled_path = tempfile::tempdir().unwrap().path().to_path_buf();
79+
let mut sled_store_builder = SledStateStore::builder().path(sled_path);
80+
if let Some(password) = encryption_password {
81+
sled_store_builder = sled_store_builder.passphrase(password.to_owned());
82+
}
83+
let sled_store = sled_store_builder.build().expect("Can't create sled store");
84+
runtime
85+
.block_on(sled_store.save_changes(&changes))
86+
.expect("initial filling of sled failed");
87+
88+
group.bench_with_input(
89+
BenchmarkId::new(format!("sled store {encrypted_suffix}"), NAME),
90+
&sled_store,
91+
|b, store| {
92+
b.to_async(&runtime).iter(|| async {
93+
let client = Client::builder()
94+
.homeserver_url("https://matrix.example.com")
95+
.store_config(StoreConfig::new().state_store(store.clone()))
96+
.build()
97+
.await
98+
.expect("Can't build client");
99+
client
100+
.restore_session(session.clone())
101+
.await
102+
.expect("couldn't restore session");
103+
})
104+
},
105+
);
106+
107+
// Sqlite
108+
let sqlite_dir = tempfile::tempdir().unwrap();
109+
let sqlite_store = runtime
110+
.block_on(SqliteStateStore::open(sqlite_dir.path(), encryption_password))
111+
.unwrap();
112+
runtime
113+
.block_on(sqlite_store.save_changes(&changes))
114+
.expect("initial filling of sqlite failed");
115+
116+
group.bench_with_input(
117+
BenchmarkId::new(format!("sqlite store {encrypted_suffix}"), NAME),
118+
&sqlite_store,
119+
|b, store| {
120+
b.to_async(&runtime).iter(|| async {
121+
let client = Client::builder()
122+
.homeserver_url("https://matrix.example.com")
123+
.store_config(StoreConfig::new().state_store(store.clone()))
124+
.build()
125+
.await
126+
.expect("Can't build client");
127+
client
128+
.restore_session(session.clone())
129+
.await
130+
.expect("couldn't restore session");
131+
})
132+
},
133+
);
134+
135+
{
136+
let _guard = runtime.enter();
137+
drop(sqlite_store);
138+
}
139+
}
140+
141+
group.finish()
142+
}
143+
144+
criterion_group! {
145+
name = benches;
146+
config = criterion();
147+
targets = restore_session
148+
}
149+
criterion_main!(benches);

bindings/matrix-sdk-crypto-js/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Add a missing `const` for compatibility with ECMAScript Module compatibility
66
mode.
77
- Fix the body of `SignatureUploadRequest`s to match the spec.
8+
- Add a constructor for `SigningKeysUploadRequest`.
89

910
# v0.1.0-alpha.8
1011

bindings/matrix-sdk-crypto-js/src/requests.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,12 @@ pub struct SigningKeysUploadRequest {
324324

325325
#[wasm_bindgen]
326326
impl SigningKeysUploadRequest {
327+
/// Create a new `SigningKeysUploadRequest`.
328+
#[wasm_bindgen(constructor)]
329+
pub fn new(id: JsString, body: JsString) -> SigningKeysUploadRequest {
330+
Self { id: Some(id), body }
331+
}
332+
327333
/// Get its request type.
328334
#[wasm_bindgen(getter, js_name = "type")]
329335
pub fn request_type(&self) -> RequestType {

bindings/matrix-sdk-ffi/src/sliding_sync.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,19 @@ impl SlidingSync {
745745
self.inner.add_list(unwrap_or_clone_arc(list_builder).inner).unwrap();
746746
}
747747

748+
pub fn add_cached_list(
749+
&self,
750+
list_builder: Arc<SlidingSyncListBuilder>,
751+
) -> Result<Option<Arc<SlidingSyncList>>, ClientError> {
752+
RUNTIME.block_on(async move {
753+
Ok(self
754+
.inner
755+
.add_cached_list(list_builder.inner.clone())
756+
.await?
757+
.map(|inner| Arc::new(SlidingSyncList { inner })))
758+
})
759+
}
760+
748761
pub fn reset_lists(&self) -> Result<(), SlidingSyncError> {
749762
self.inner.reset_lists().map_err(Into::into)
750763
}
@@ -815,6 +828,17 @@ impl SlidingSyncBuilder {
815828
Arc::new(builder)
816829
}
817830

831+
pub fn add_cached_list(
832+
self: Arc<Self>,
833+
list_builder: Arc<SlidingSyncListBuilder>,
834+
) -> Result<Arc<Self>, ClientError> {
835+
let mut builder = unwrap_or_clone_arc(self);
836+
let list_builder = unwrap_or_clone_arc(list_builder);
837+
builder.inner = RUNTIME
838+
.block_on(async move { builder.inner.add_cached_list(list_builder.inner).await })?;
839+
Ok(Arc::new(builder))
840+
}
841+
818842
pub fn with_common_extensions(self: Arc<Self>) -> Arc<Self> {
819843
let mut builder = unwrap_or_clone_arc(self);
820844
builder.inner = builder.inner.with_common_extensions();

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

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub struct SlidingSyncBuilder {
3535
bump_event_types: Vec<TimelineEventType>,
3636
extensions: Option<ExtensionsConfig>,
3737
subscriptions: BTreeMap<OwnedRoomId, v4::RoomSubscription>,
38+
rooms: BTreeMap<OwnedRoomId, SlidingSyncRoom>,
3839
}
3940

4041
impl SlidingSyncBuilder {
@@ -47,6 +48,7 @@ impl SlidingSyncBuilder {
4748
bump_event_types: Vec::new(),
4849
extensions: None,
4950
subscriptions: BTreeMap::new(),
51+
rooms: BTreeMap::new(),
5052
}
5153
}
5254

@@ -64,12 +66,35 @@ impl SlidingSyncBuilder {
6466

6567
/// Add the given list to the lists.
6668
///
67-
/// Replace any list with the name.
69+
/// Replace any list with the same name.
6870
pub fn add_list(mut self, list_builder: SlidingSyncListBuilder) -> Self {
6971
self.lists.push(list_builder);
7072
self
7173
}
7274

75+
/// Enroll the list in caching, reloads it from the cache if possible, and
76+
/// adds it to the list of lists.
77+
///
78+
/// This will raise an error if a [`storage_key()`][Self::storage_key] was
79+
/// not set, or if there was a I/O error reading from the cache.
80+
///
81+
/// Replace any list with the same name.
82+
pub async fn add_cached_list(mut self, mut list: SlidingSyncListBuilder) -> Result<Self> {
83+
let Some(ref storage_key) = self.storage_key else {
84+
return Err(super::error::Error::MissingStorageKeyForCaching.into());
85+
};
86+
87+
let reloaded_rooms = list.set_cached_and_reload(&self.client, storage_key).await?;
88+
89+
for (key, frozen) in reloaded_rooms {
90+
self.rooms
91+
.entry(key)
92+
.or_insert_with(|| SlidingSyncRoom::from_frozen(frozen, self.client.clone()));
93+
}
94+
95+
Ok(self.add_list(list))
96+
}
97+
7398
/// Activate e2ee, to-device-message and account data extensions if not yet
7499
/// configured.
75100
///
@@ -204,7 +229,6 @@ impl SlidingSyncBuilder {
204229
let client = self.client;
205230

206231
let mut delta_token = None;
207-
let mut rooms_found: BTreeMap<OwnedRoomId, SlidingSyncRoom> = BTreeMap::new();
208232

209233
let (internal_channel_sender, internal_channel_receiver) = channel(8);
210234

@@ -221,15 +245,14 @@ impl SlidingSyncBuilder {
221245
restore_sliding_sync_state(
222246
&client,
223247
storage_key,
224-
&mut lists,
248+
&lists,
225249
&mut delta_token,
226-
&mut rooms_found,
227250
&mut self.extensions,
228251
)
229252
.await?;
230253
}
231254

232-
let rooms = StdRwLock::new(rooms_found);
255+
let rooms = StdRwLock::new(self.rooms);
233256
let lists = StdRwLock::new(lists);
234257

235258
Ok(SlidingSync::new(SlidingSyncInner {

0 commit comments

Comments
 (0)