mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-14 19:16:02 -04:00
fix(sdk): Make event handler futures non-Send on wasm
This commit is contained in:
committed by
Jonas Platte
parent
0701561e45
commit
ad80839ffd
@@ -1,6 +1,8 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
#![warn(missing_debug_implementations)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
pub use instant;
|
||||
|
||||
pub mod deserialized_responses;
|
||||
@@ -36,6 +38,13 @@ pub trait SyncOutsideWasm {}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
impl<T> SyncOutsideWasm for T {}
|
||||
|
||||
/// Alias for `Future + SendOutsideWasm`.
|
||||
///
|
||||
/// Useful as a separate trait because the former trait bound can't be used
|
||||
/// with `dyn`.
|
||||
pub trait FutureSendOutsideWasm: Future + SendOutsideWasm {}
|
||||
impl<T: Future + SendOutsideWasm> FutureSendOutsideWasm for T {}
|
||||
|
||||
/// Super trait that is used for our store traits, this trait will differ if
|
||||
/// it's used on WASM. WASM targets will not require `Send` and `Sync` to have
|
||||
/// implemented, while other targets will.
|
||||
|
||||
@@ -32,7 +32,7 @@ use futures_signals::signal::Signal;
|
||||
use matrix_sdk_base::{
|
||||
deserialized_responses::SyncResponse,
|
||||
media::{MediaEventContent, MediaFormat, MediaRequest, MediaThumbnailSize},
|
||||
BaseClient, Session, SessionMeta, SessionTokens, StateStore,
|
||||
BaseClient, FutureSendOutsideWasm, Session, SessionMeta, SessionTokens, StateStore,
|
||||
};
|
||||
use matrix_sdk_common::{
|
||||
instant::{Duration, Instant},
|
||||
@@ -110,7 +110,7 @@ const MIN_UPLOAD_REQUEST_TIMEOUT: Duration = Duration::from_secs(60 * 5);
|
||||
|
||||
type EventHandlerMap = BTreeMap<EventHandlerKey, Vec<EventHandlerWrapper>>;
|
||||
|
||||
type NotificationHandlerFut = Pin<Box<dyn Future<Output = ()> + Send>>;
|
||||
type NotificationHandlerFut = Pin<Box<dyn FutureSendOutsideWasm<Output = ()>>>;
|
||||
type NotificationHandlerFn =
|
||||
Box<dyn Fn(Notification, room::Room, Client) -> NotificationHandlerFut + Send + Sync>;
|
||||
|
||||
|
||||
@@ -43,7 +43,10 @@ use std::{
|
||||
sync::atomic::Ordering::SeqCst,
|
||||
};
|
||||
|
||||
use matrix_sdk_base::deserialized_responses::{EncryptionInfo, SyncRoomEvent};
|
||||
use matrix_sdk_base::{
|
||||
deserialized_responses::{EncryptionInfo, SyncRoomEvent},
|
||||
FutureSendOutsideWasm, SendOutsideWasm,
|
||||
};
|
||||
use ruma::{events::AnySyncStateEvent, serde::Raw, OwnedRoomId};
|
||||
use serde::{de::DeserializeOwned, Deserialize};
|
||||
use serde_json::value::RawValue as RawJsonValue;
|
||||
@@ -51,7 +54,7 @@ use tracing::{error, warn};
|
||||
|
||||
use crate::{room, Client};
|
||||
|
||||
type EventHandlerFut = Pin<Box<dyn Future<Output = ()> + Send>>;
|
||||
type EventHandlerFut = Pin<Box<dyn FutureSendOutsideWasm<Output = ()>>>;
|
||||
type EventHandlerFn = dyn Fn(EventHandlerData<'_>) -> EventHandlerFut + Send + Sync;
|
||||
|
||||
#[doc(hidden)]
|
||||
@@ -181,7 +184,7 @@ impl EventHandlerContext for EventHandlerHandle {
|
||||
pub trait EventHandler<Ev, Ctx>: Send + Sync + 'static {
|
||||
/// The future returned by `handle_event`.
|
||||
#[doc(hidden)]
|
||||
type Future: Future + Send + 'static;
|
||||
type Future: Future + SendOutsideWasm + 'static;
|
||||
|
||||
/// Create a future for handling the given event.
|
||||
///
|
||||
@@ -540,7 +543,7 @@ macro_rules! impl_event_handler {
|
||||
where
|
||||
Ev: SyncEvent,
|
||||
Fun: Fn(Ev, $($ty),*) -> Fut + Send + Sync + 'static,
|
||||
Fut: Future + Send + 'static,
|
||||
Fut: Future + SendOutsideWasm + 'static,
|
||||
Fut::Output: EventHandlerResult,
|
||||
$($ty: EventHandlerContext),*
|
||||
{
|
||||
@@ -949,4 +952,20 @@ mod tests {
|
||||
|
||||
assert_eq!(client.event_handlers().len(), 0);
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn use_client_in_handler() {
|
||||
// This used to not work because we were requiring `Send` of event
|
||||
// handler futures even on WASM, where practically all futures that do
|
||||
// I/O aren't.
|
||||
let client = no_retry_test_client(None).await;
|
||||
|
||||
client.add_event_handler(|_ev: OriginalSyncRoomMemberEvent, client: Client| async move {
|
||||
// All of Client's async methods that do network requests (and
|
||||
// possibly some that don't) are `!Send` on wasm. We obviously want
|
||||
// to be able to use them in event handlers.
|
||||
let _caps = client.get_capabilities().await?;
|
||||
anyhow::Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user