Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into release-matrix-sdk-cr…
Browse files Browse the repository at this point in the history
…ypto-js-0.1.0-alpha.9
  • Loading branch information
richvdh committed May 15, 2023
2 parents 89bf7f2 + 923d425 commit 6c0afae
Show file tree
Hide file tree
Showing 12 changed files with 554 additions and 122 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ publish = false

[dependencies]
criterion = { version = "0.4.0", features = ["async", "async_tokio", "html_reports"] }
matrix-sdk-base = { path = "../crates/matrix-sdk-base" }
matrix-sdk-crypto = { path = "../crates/matrix-sdk-crypto", version = "0.6.0"}
matrix-sdk-sqlite = { path = "../crates/matrix-sdk-sqlite", version = "0.1.0", default-features = false, features = ["crypto-store"] }
matrix-sdk-sled = { path = "../crates/matrix-sdk-sled", version = "0.2.0", default-features = false, features = ["crypto-store"] }
matrix-sdk-sled = { path = "../crates/matrix-sdk-sled", version = "0.2.0", features = ["crypto-store"] }
matrix-sdk-test = { path = "../testing/matrix-sdk-test", version = "0.6.0"}
matrix-sdk = { path = "../crates/matrix-sdk" }
ruma = { workspace = true }
serde_json = { workspace = true }
tempfile = "3.3.0"
Expand All @@ -24,3 +26,7 @@ pprof = { version = "0.11.0", features = ["flamegraph", "criterion"] }
[[bench]]
name = "crypto_bench"
harness = false

[[bench]]
name = "store_bench"
harness = false
149 changes: 149 additions & 0 deletions benchmarks/benches/store_bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use criterion::*;
use matrix_sdk::{config::StoreConfig, Client, RoomInfo, RoomState, Session, StateChanges};
use matrix_sdk_base::{store::MemoryStore, StateStore as _};
use matrix_sdk_sled::SledStateStore;
use matrix_sdk_sqlite::SqliteStateStore;
use ruma::{device_id, user_id, RoomId};
use tokio::runtime::Builder;

fn criterion() -> Criterion {
#[cfg(target_os = "linux")]
let criterion = Criterion::default().with_profiler(pprof::criterion::PProfProfiler::new(
100,
pprof::criterion::Output::Flamegraph(None),
));

#[cfg(not(target_os = "linux"))]
let criterion = Criterion::default();

criterion
}

/// Number of joined rooms in the benchmark.
const NUM_JOINED_ROOMS: usize = 10000;

/// Number of stripped rooms in the benchmark.
const NUM_STRIPPED_JOINED_ROOMS: usize = 10000;

pub fn restore_session(c: &mut Criterion) {
let runtime = Builder::new_multi_thread().build().expect("Can't create runtime");

// Create a fake list of changes, and a session to recover from.
let mut changes = StateChanges::default();

for i in 0..NUM_JOINED_ROOMS {
let room_id = RoomId::parse(format!("!room{i}:example.com")).unwrap().to_owned();
changes.add_room(RoomInfo::new(&room_id, RoomState::Joined));
}

for i in 0..NUM_STRIPPED_JOINED_ROOMS {
let room_id = RoomId::parse(format!("!strippedroom{i}:example.com")).unwrap().to_owned();
changes.add_stripped_room(RoomInfo::new(&room_id, RoomState::Joined));
}

let session = Session {
access_token: "OHEY".to_owned(),
refresh_token: None,
user_id: user_id!("@somebody:example.com").to_owned(),
device_id: device_id!("DEVICE_ID").to_owned(),
};

// Start the benchmark.

let mut group = c.benchmark_group("Client reload");
group.throughput(Throughput::Elements(100));

const NAME: &str = "restore a session";

// Memory
let mem_store = MemoryStore::new();
runtime.block_on(mem_store.save_changes(&changes)).expect("initial filling of mem failed");

group.bench_with_input(BenchmarkId::new("memory store", NAME), &mem_store, |b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client.restore_session(session.clone()).await.expect("couldn't restore session");
})
});

for encryption_password in [None, Some("hunter2")] {
let encrypted_suffix = if encryption_password.is_some() { "encrypted" } else { "clear" };

// Sled
let sled_path = tempfile::tempdir().unwrap().path().to_path_buf();
let mut sled_store_builder = SledStateStore::builder().path(sled_path);
if let Some(password) = encryption_password {
sled_store_builder = sled_store_builder.passphrase(password.to_owned());
}
let sled_store = sled_store_builder.build().expect("Can't create sled store");
runtime
.block_on(sled_store.save_changes(&changes))
.expect("initial filling of sled failed");

group.bench_with_input(
BenchmarkId::new(format!("sled store {encrypted_suffix}"), NAME),
&sled_store,
|b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client
.restore_session(session.clone())
.await
.expect("couldn't restore session");
})
},
);

// Sqlite
let sqlite_dir = tempfile::tempdir().unwrap();
let sqlite_store = runtime
.block_on(SqliteStateStore::open(sqlite_dir.path(), encryption_password))
.unwrap();
runtime
.block_on(sqlite_store.save_changes(&changes))
.expect("initial filling of sqlite failed");

group.bench_with_input(
BenchmarkId::new(format!("sqlite store {encrypted_suffix}"), NAME),
&sqlite_store,
|b, store| {
b.to_async(&runtime).iter(|| async {
let client = Client::builder()
.homeserver_url("https://matrix.example.com")
.store_config(StoreConfig::new().state_store(store.clone()))
.build()
.await
.expect("Can't build client");
client
.restore_session(session.clone())
.await
.expect("couldn't restore session");
})
},
);

{
let _guard = runtime.enter();
drop(sqlite_store);
}
}

group.finish()
}

criterion_group! {
name = benches;
config = criterion();
targets = restore_session
}
criterion_main!(benches);
1 change: 1 addition & 0 deletions bindings/matrix-sdk-crypto-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Add a missing `const` for compatibility with ECMAScript Module compatibility
mode.
- Fix the body of `SignatureUploadRequest`s to match the spec.
- Add a constructor for `SigningKeysUploadRequest`.

# v0.1.0-alpha.8

Expand Down
6 changes: 6 additions & 0 deletions bindings/matrix-sdk-crypto-js/src/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,12 @@ pub struct SigningKeysUploadRequest {

#[wasm_bindgen]
impl SigningKeysUploadRequest {
/// Create a new `SigningKeysUploadRequest`.
#[wasm_bindgen(constructor)]
pub fn new(id: JsString, body: JsString) -> SigningKeysUploadRequest {
Self { id: Some(id), body }
}

/// Get its request type.
#[wasm_bindgen(getter, js_name = "type")]
pub fn request_type(&self) -> RequestType {
Expand Down
24 changes: 24 additions & 0 deletions bindings/matrix-sdk-ffi/src/sliding_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,19 @@ impl SlidingSync {
self.inner.add_list(unwrap_or_clone_arc(list_builder).inner).unwrap();
}

pub fn add_cached_list(
&self,
list_builder: Arc<SlidingSyncListBuilder>,
) -> Result<Option<Arc<SlidingSyncList>>, ClientError> {
RUNTIME.block_on(async move {
Ok(self
.inner
.add_cached_list(list_builder.inner.clone())
.await?
.map(|inner| Arc::new(SlidingSyncList { inner })))
})
}

pub fn reset_lists(&self) -> Result<(), SlidingSyncError> {
self.inner.reset_lists().map_err(Into::into)
}
Expand Down Expand Up @@ -815,6 +828,17 @@ impl SlidingSyncBuilder {
Arc::new(builder)
}

pub fn add_cached_list(
self: Arc<Self>,
list_builder: Arc<SlidingSyncListBuilder>,
) -> Result<Arc<Self>, ClientError> {
let mut builder = unwrap_or_clone_arc(self);
let list_builder = unwrap_or_clone_arc(list_builder);
builder.inner = RUNTIME
.block_on(async move { builder.inner.add_cached_list(list_builder.inner).await })?;
Ok(Arc::new(builder))
}

pub fn with_common_extensions(self: Arc<Self>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.inner = builder.inner.with_common_extensions();
Expand Down
33 changes: 28 additions & 5 deletions crates/matrix-sdk/src/sliding_sync/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub struct SlidingSyncBuilder {
bump_event_types: Vec<TimelineEventType>,
extensions: Option<ExtensionsConfig>,
subscriptions: BTreeMap<OwnedRoomId, v4::RoomSubscription>,
rooms: BTreeMap<OwnedRoomId, SlidingSyncRoom>,
}

impl SlidingSyncBuilder {
Expand All @@ -47,6 +48,7 @@ impl SlidingSyncBuilder {
bump_event_types: Vec::new(),
extensions: None,
subscriptions: BTreeMap::new(),
rooms: BTreeMap::new(),
}
}

Expand All @@ -64,12 +66,35 @@ impl SlidingSyncBuilder {

/// Add the given list to the lists.
///
/// Replace any list with the name.
/// Replace any list with the same name.
pub fn add_list(mut self, list_builder: SlidingSyncListBuilder) -> Self {
self.lists.push(list_builder);
self
}

/// Enroll the list in caching, reloads it from the cache if possible, and
/// adds it to the list of lists.
///
/// This will raise an error if a [`storage_key()`][Self::storage_key] was
/// not set, or if there was a I/O error reading from the cache.
///
/// Replace any list with the same name.
pub async fn add_cached_list(mut self, mut list: SlidingSyncListBuilder) -> Result<Self> {
let Some(ref storage_key) = self.storage_key else {
return Err(super::error::Error::MissingStorageKeyForCaching.into());
};

let reloaded_rooms = list.set_cached_and_reload(&self.client, storage_key).await?;

for (key, frozen) in reloaded_rooms {
self.rooms
.entry(key)
.or_insert_with(|| SlidingSyncRoom::from_frozen(frozen, self.client.clone()));
}

Ok(self.add_list(list))
}

/// Activate e2ee, to-device-message and account data extensions if not yet
/// configured.
///
Expand Down Expand Up @@ -204,7 +229,6 @@ impl SlidingSyncBuilder {
let client = self.client;

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

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

Expand All @@ -221,15 +245,14 @@ impl SlidingSyncBuilder {
restore_sliding_sync_state(
&client,
storage_key,
&mut lists,
&lists,
&mut delta_token,
&mut rooms_found,
&mut self.extensions,
)
.await?;
}

let rooms = StdRwLock::new(rooms_found);
let rooms = StdRwLock::new(self.rooms);
let lists = StdRwLock::new(lists);

Ok(SlidingSync::new(SlidingSyncInner {
Expand Down
Loading

0 comments on commit 6c0afae

Please sign in to comment.