Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

matrix-sdk-ui: compile on wasm #3333

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ jobs:
- name: '[m], indexeddb stores, no crypto'
cmd: matrix-sdk-indexeddb-stores-no-crypto

- name: '[m]-sdk-ui'
cmd: matrix-sdk-ui

steps:
- name: Checkout the repo
uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ sha2 = "0.10.8"
similar-asserts = "1.5.0"
stream_assert = "0.1.1"
thiserror = "1.0.38"
tokio = { version = "1.30.0", default-features = false, features = ["sync"] }
tokio = { version = "1.30.0", default-features = false, features = ["sync", "macros"] }
tokio-stream = "0.1.14"
tracing = { version = "0.1.40", default-features = false, features = ["std"] }
tracing-core = "0.1.32"
Expand Down
7 changes: 5 additions & 2 deletions crates/matrix-sdk-base/src/read_receipts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ use std::{
};

use eyeball_im::Vector;
use matrix_sdk_common::{deserialized_responses::SyncTimelineEvent, ring_buffer::RingBuffer};
use matrix_sdk_common::{
deserialized_responses::SyncTimelineEvent, ring_buffer::RingBuffer, SendOutsideWasm,
SyncOutsideWasm,
};
use ruma::{
events::{
poll::{start::PollStartEventContent, unstable_start::UnstablePollStartEventContent},
Expand Down Expand Up @@ -266,7 +269,7 @@ impl RoomReadReceipts {
}

/// Provider for timeline events prior to the current sync.
pub trait PreviousEventsProvider: Send + Sync {
pub trait PreviousEventsProvider: SendOutsideWasm + SyncOutsideWasm {
/// Returns the list of known timeline events, in sync order, for the given
/// room.
fn for_room(&self, room_id: &RoomId) -> Vector<SyncTimelineEvent>;
Expand Down
45 changes: 22 additions & 23 deletions crates/matrix-sdk-common/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ use std::{
#[cfg(target_arch = "wasm32")]
pub use futures_util::future::Aborted as JoinError;
#[cfg(target_arch = "wasm32")]
use futures_util::{
future::{AbortHandle, Abortable, RemoteHandle},
FutureExt,
};
use futures_util::{future::RemoteHandle, FutureExt};
#[cfg(not(target_arch = "wasm32"))]
pub use tokio::task::{spawn, JoinError, JoinHandle};

Expand All @@ -37,30 +34,32 @@ pub fn spawn<F, T>(future: F) -> JoinHandle<T>
where
F: Future<Output = T> + 'static,
{
let (future, remote_handle) = future.remote_handle();
let (abort_handle, abort_registration) = AbortHandle::new_pair();
let future = Abortable::new(future, abort_registration);

wasm_bindgen_futures::spawn_local(async {
// Poll the future, and ignore the result (either it's `Ok(())`, or it's
// `Err(Aborted)`).
let _ = future.await;
});
let (fut, handle) = future.remote_handle();
wasm_bindgen_futures::spawn_local(fut);

JoinHandle { remote_handle, abort_handle }
JoinHandle { handle: Some(handle) }
}

#[cfg(target_arch = "wasm32")]
#[derive(Debug)]
pub struct JoinHandle<T> {
remote_handle: RemoteHandle<T>,
abort_handle: AbortHandle,
handle: Option<RemoteHandle<T>>,
}

#[cfg(target_arch = "wasm32")]
impl<T> JoinHandle<T> {
pub fn abort(&self) {
self.abort_handle.abort();
pub fn abort(&mut self) {
drop(self.handle.take());
}
}

#[cfg(target_arch = "wasm32")]
impl<T> Drop for JoinHandle<T> {
fn drop(&mut self) {
// don't abort the spawned future
if let Some(h) = self.handle.take() {
h.forget();
}
}
}

Expand All @@ -69,11 +68,10 @@ impl<T: 'static> Future for JoinHandle<T> {
type Output = Result<T, JoinError>;

fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.abort_handle.is_aborted() {
// The future has been aborted. It is not possible to poll it again.
Poll::Ready(Err(JoinError))
if let Some(handle) = self.handle.as_mut() {
Pin::new(handle).poll(cx).map(Ok)
} else {
Pin::new(&mut self.remote_handle).poll(cx).map(Ok)
Poll::Ready(Err(JoinError))
}
}
}
Expand All @@ -96,7 +94,8 @@ mod tests {
#[async_test]
async fn test_abort() {
let future = async { 42 };
let join_handle = spawn(future);
#[allow(unused_mut)]
let mut join_handle = spawn(future);

join_handle.abort();

Expand Down
4 changes: 2 additions & 2 deletions crates/matrix-sdk-common/src/timeout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl Error for ElapsedError {}
/// an error.
pub async fn timeout<F, T>(future: F, duration: Duration) -> Result<T, ElapsedError>
where
F: Future<Output = T> + Unpin,
F: Future<Output = T>,
{
#[cfg(not(target_arch = "wasm32"))]
return tokio_timeout(duration, future).await.map_err(|_| ElapsedError(()));
Expand All @@ -51,7 +51,7 @@ where
let timeout_future =
TimeoutFuture::new(u32::try_from(duration.as_millis()).expect("Overlong duration"));

match select(future, timeout_future).await {
match select(std::pin::pin!(future), timeout_future).await {
Either::Left((res, _)) => Ok(res),
Either::Right((_, _)) => Err(ElapsedError(())),
}
Expand Down
4 changes: 2 additions & 2 deletions crates/matrix-sdk-common/src/tracing_timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::time::Instant;

use tracing::{callsite::DefaultCallsite, Callsite as _};

use crate::instant::Instant;

/// A named RAII that will show on Drop how long its covered section took to
/// execute.
pub struct TracingTimer {
Expand Down
3 changes: 3 additions & 0 deletions crates/matrix-sdk-ui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ wiremock = { workspace = true }

[lints]
workspace = true

[target.'cfg(target_arch = "wasm32")'.dependencies]
gloo-timers = { version = "0.3.0", features = ["futures"] }
3 changes: 3 additions & 0 deletions crates/matrix-sdk-ui/src/encryption_sync_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ impl EncryptionSyncService {
LEASE_DURATION_MS
);

#[cfg(not(target_arch = "wasm32"))]
tokio::time::sleep(Duration::from_millis(LEASE_DURATION_MS.into())).await;
#[cfg(target_arch = "wasm32")]
gloo_timers::future::TimeoutFuture::new(LEASE_DURATION_MS).await;

lock_guard = self
.client
Expand Down
3 changes: 3 additions & 0 deletions crates/matrix-sdk-ui/src/notification_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,10 @@ impl NotificationClient {
for _ in 0..3 {
trace!("waiting for decryption…");

#[cfg(not(target_arch = "wasm32"))]
tokio::time::sleep(Duration::from_millis(wait)).await;
#[cfg(target_arch = "wasm32")]
gloo_timers::future::TimeoutFuture::new(wait).await;

match room.decrypt_event(raw_event.cast_ref()).await {
Ok(new_event) => {
Expand Down
9 changes: 5 additions & 4 deletions crates/matrix-sdk-ui/src/room_list_service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ use eyeball::{SharedObservable, Subscriber};
use futures_util::{pin_mut, Stream, StreamExt};
pub use matrix_sdk::RoomListEntry;
use matrix_sdk::{
event_cache::EventCacheError, sliding_sync::Ranges, Client, Error as SlidingSyncError,
SlidingSync, SlidingSyncList, SlidingSyncListBuilder, SlidingSyncMode,
event_cache::EventCacheError, sliding_sync::Ranges, timeout::timeout, Client,
Error as SlidingSyncError, SlidingSync, SlidingSyncList, SlidingSyncListBuilder,
SlidingSyncMode,
};
use matrix_sdk_base::ring_buffer::RingBuffer;
pub use room::*;
Expand All @@ -95,7 +96,7 @@ use ruma::{
};
pub use state::*;
use thiserror::Error;
use tokio::{sync::Mutex, time::timeout};
use tokio::sync::Mutex;

use crate::timeline;

Expand Down Expand Up @@ -347,7 +348,7 @@ impl RoomListService {
};

// `state.next().await` has a maximum of `yield_delay` time to execute…
let next_state = match timeout(yield_delay, state.next()).await {
let next_state = match timeout(state.next(), yield_delay).await {
// A new state has been received before `yield_delay` time. The new
// `sync_indicator` value won't be yielded.
Ok(next_state) => next_state,
Expand Down
18 changes: 12 additions & 6 deletions crates/matrix-sdk-ui/src/room_list_service/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ impl State {
}

/// A trait to define what an `Action` is.
#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
trait Action {
async fn run(&self, sliding_sync: &SlidingSync) -> Result<(), Error>;
}
Expand All @@ -104,7 +105,8 @@ pub const VISIBLE_ROOMS_DEFAULT_TIMELINE_LIMIT: Bound = 20;
/// Default range for the `VISIBLE_ROOMS_LIST_NAME` list.
pub const VISIBLE_ROOMS_DEFAULT_RANGE: Range = 0..=19;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl Action for AddVisibleRooms {
async fn run(&self, sliding_sync: &SlidingSync) -> Result<(), Error> {
sliding_sync
Expand All @@ -128,7 +130,8 @@ impl Action for AddVisibleRooms {

struct SetVisibleRoomsToZeroTimelineLimit;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl Action for SetVisibleRoomsToZeroTimelineLimit {
async fn run(&self, sliding_sync: &SlidingSync) -> Result<(), Error> {
sliding_sync
Expand All @@ -146,7 +149,8 @@ impl Action for SetVisibleRoomsToZeroTimelineLimit {

struct SetVisibleRoomsToDefaultTimelineLimit;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl Action for SetVisibleRoomsToDefaultTimelineLimit {
async fn run(&self, sliding_sync: &SlidingSync) -> Result<(), Error> {
sliding_sync
Expand All @@ -168,7 +172,8 @@ struct SetAllRoomsToSelectiveSyncMode;
/// `ALL_ROOMS_LIST_NAME` list.
pub const ALL_ROOMS_DEFAULT_SELECTIVE_RANGE: Range = 0..=19;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl Action for SetAllRoomsToSelectiveSyncMode {
async fn run(&self, sliding_sync: &SlidingSync) -> Result<(), Error> {
sliding_sync
Expand All @@ -192,7 +197,8 @@ struct SetAllRoomsToGrowingSyncMode;
/// list.
pub const ALL_ROOMS_DEFAULT_GROWING_BATCH_SIZE: u32 = 100;

#[async_trait]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl Action for SetAllRoomsToGrowingSyncMode {
async fn run(&self, sliding_sync: &SlidingSync) -> Result<(), Error> {
sliding_sync
Expand Down
14 changes: 7 additions & 7 deletions crates/matrix-sdk-ui/src/sync_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ use std::sync::{Arc, Mutex};
use eyeball::{SharedObservable, Subscriber};
use futures_core::Future;
use futures_util::{pin_mut, StreamExt as _};
use matrix_sdk::Client;
use matrix_sdk::{
executor::{spawn, JoinHandle},
Client,
};
use thiserror::Error;
use tokio::{
sync::{
mpsc::{Receiver, Sender},
Mutex as AsyncMutex, OwnedMutexGuard,
},
task::{spawn, JoinHandle},
use tokio::sync::{
mpsc::{Receiver, Sender},
Mutex as AsyncMutex, OwnedMutexGuard,
};
use tracing::{error, info, instrument, trace, warn, Instrument, Level};

Expand Down
27 changes: 19 additions & 8 deletions crates/matrix-sdk-ui/src/timeline/futures.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::{fs, future::IntoFuture, path::PathBuf};

#[cfg(not(target_arch = "wasm32"))]
use eyeball::{SharedObservable, Subscriber};
use matrix_sdk::{attachment::AttachmentConfig, TransmissionProgress};
use matrix_sdk::attachment::AttachmentConfig;
#[cfg(not(target_arch = "wasm32"))]
use matrix_sdk::TransmissionProgress;
use matrix_sdk_base::boxed_into_future;
use mime::Mime;
use tracing::{Instrument as _, Span};
Expand All @@ -14,6 +17,7 @@ pub struct SendAttachment<'a> {
mime_type: Mime,
config: AttachmentConfig,
tracing_span: Span,
#[cfg(not(target_arch = "wasm32"))]
pub(crate) send_progress: SharedObservable<TransmissionProgress>,
}

Expand All @@ -30,6 +34,7 @@ impl<'a> SendAttachment<'a> {
mime_type,
config,
tracing_span: Span::current(),
#[cfg(not(target_arch = "wasm32"))]
send_progress: Default::default(),
}
}
Expand All @@ -47,7 +52,15 @@ impl<'a> IntoFuture for SendAttachment<'a> {
boxed_into_future!(extra_bounds: 'a);

fn into_future(self) -> Self::IntoFuture {
let Self { timeline, path, mime_type, config, tracing_span, send_progress } = self;
let Self {
timeline,
path,
mime_type,
config,
tracing_span,
#[cfg(not(target_arch = "wasm32"))]
send_progress,
} = self;
let fut = async move {
let filename = path
.file_name()
Expand All @@ -56,12 +69,10 @@ impl<'a> IntoFuture for SendAttachment<'a> {
.ok_or(Error::InvalidAttachmentFileName)?;
let data = fs::read(&path).map_err(|_| Error::InvalidAttachmentData)?;

timeline
.room()
.send_attachment(filename, &mime_type, data, config)
.with_send_progress_observable(send_progress)
.await
.map_err(|_| Error::FailedSendingAttachment)?;
let value = timeline.room().send_attachment(path, &mime_type, data, config);
#[cfg(not(target_arch = "wasm32"))]
let value = value.with_send_progress_observable(send_progress);
value.await.map_err(|_| Error::FailedSendingAttachment)?;

Ok(())
};
Expand Down
4 changes: 1 addition & 3 deletions crates/matrix-sdk-ui/src/timeline/inner/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#[cfg(feature = "e2e-encryption")]
use std::collections::BTreeSet;
use std::{fmt, sync::Arc};
use std::{collections::BTreeSet, fmt, sync::Arc};

use as_variant::as_variant;
use eyeball_im::{ObservableVectorEntry, VectorDiff};
Expand Down
Loading
Loading