From ff3b166ca30d6094ae3e35e1e16b9ba170a78b65 Mon Sep 17 00:00:00 2001 From: Jonathan Alter Date: Wed, 30 Apr 2025 23:39:43 -0500 Subject: [PATCH 1/2] add support for wasm32-unknown-unknown target --- Cargo.toml | 11 +++++++++-- src/lib.rs | 1 + src/mysql/mod.rs | 1 + src/pg/mod.rs | 14 ++++++++++++++ src/pooled_connection/mod.rs | 1 + src/sync_connection_wrapper/mod.rs | 1 + 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 91c5265..abee693 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,6 @@ futures-util = { version = "0.3.17", default-features = false, features = [ "std", "sink", ] } -tokio-postgres = { version = "0.7.10", optional = true } -tokio = { version = "1.26", optional = true } mysql_async = { version = "0.36.0", optional = true, default-features = false, features = [ "minimal-rust", ] } @@ -36,6 +34,15 @@ deadpool = { version = "0.12", optional = true, default-features = false, featur mobc = { version = ">=0.7,<0.10", optional = true } scoped-futures = { version = "0.1", features = ["std"] } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tokio-postgres = { version = "0.7.10", optional = true } +tokio = { version = "1.26", optional = true } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +tokio-postgres = { version = "0.7.10", optional = true, default-features = false, features = ["js"] } +tokio = { version = "1.26", optional = true, default-features = false } +wasm-bindgen-futures = { version = "0.4.50" } + [dependencies.diesel] version = "~2.2.0" default-features = false diff --git a/src/lib.rs b/src/lib.rs index 5ae0136..fd21c0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -149,6 +149,7 @@ pub trait AsyncConnection: SimpleAsyncConnection + Sized + Send { /// The argument to this method and the method's behavior varies by backend. /// See the documentation for that backend's connection class /// for details about what it accepts and how it behaves. + #[cfg(not(target_arch = "wasm32"))] fn establish(database_url: &str) -> impl Future> + Send; /// Executes the given function inside of a database transaction diff --git a/src/mysql/mod.rs b/src/mysql/mod.rs index 6f2321f..b2137e8 100644 --- a/src/mysql/mod.rs +++ b/src/mysql/mod.rs @@ -71,6 +71,7 @@ impl AsyncConnection for AsyncMysqlConnection { type TransactionManager = AnsiTransactionManager; + #[cfg(not(target_arch = "wasm32"))] async fn establish(database_url: &str) -> diesel::ConnectionResult { let mut instrumentation = DynInstrumentation::default_instrumentation(); instrumentation.on_connection_event(InstrumentationEvent::start_establish_connection( diff --git a/src/pg/mod.rs b/src/pg/mod.rs index ce24ba8..127914c 100644 --- a/src/pg/mod.rs +++ b/src/pg/mod.rs @@ -161,6 +161,7 @@ impl AsyncConnection for AsyncPgConnection { type Backend = diesel::pg::Pg; type TransactionManager = AnsiTransactionManager; + #[cfg(not(target_arch = "wasm32"))] async fn establish(database_url: &str) -> ConnectionResult { let mut instrumentation = DynInstrumentation::default_instrumentation(); instrumentation.on_connection_event(InstrumentationEvent::start_establish_connection( @@ -396,6 +397,7 @@ impl AsyncPgConnection { /// Constructs a new `AsyncPgConnection` from an existing [`tokio_postgres::Client`] and /// [`tokio_postgres::Connection`] + #[cfg(not(target_arch = "wasm32"))] pub async fn try_from_client_and_connection( client: tokio_postgres::Client, conn: tokio_postgres::Connection, @@ -877,6 +879,7 @@ async fn drive_future( } } +#[cfg(not(target_arch = "wasm32"))] fn drive_connection( conn: tokio_postgres::Connection, ) -> ( @@ -889,6 +892,7 @@ where let (error_tx, error_rx) = tokio::sync::broadcast::channel(1); let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel(); + #[cfg(not(target_arch = "wasm32"))] tokio::spawn(async move { match futures_util::future::select(shutdown_rx, conn).await { Either::Left(_) | Either::Right((Ok(_), _)) => {} @@ -898,6 +902,16 @@ where } }); + #[cfg(target_arch = "wasm32")] + wasm_bindgen_futures::spawn_local(async move { + match futures_util::future::select(shutdown_rx, conn).await { + Either::Left(_) | Either::Right((Ok(_), _)) => {} + Either::Right((Err(e), _)) => { + let _ = error_tx.send(Arc::new(e)); + } + } + }); + (error_rx, shutdown_tx) } diff --git a/src/pooled_connection/mod.rs b/src/pooled_connection/mod.rs index 4674d22..d104271 100644 --- a/src/pooled_connection/mod.rs +++ b/src/pooled_connection/mod.rs @@ -193,6 +193,7 @@ where type TransactionManager = PoolTransactionManager<::TransactionManager>; + #[cfg(not(target_arch = "wasm32"))] async fn establish(_database_url: &str) -> diesel::ConnectionResult { Err(diesel::result::ConnectionError::BadConnection( String::from("Cannot directly establish a pooled connection"), diff --git a/src/sync_connection_wrapper/mod.rs b/src/sync_connection_wrapper/mod.rs index 9f28e5b..6a4ccca 100644 --- a/src/sync_connection_wrapper/mod.rs +++ b/src/sync_connection_wrapper/mod.rs @@ -112,6 +112,7 @@ where type Backend = ::Backend; type TransactionManager = SyncTransactionManagerWrapper<::TransactionManager>; + #[cfg(not(target_arch = "wasm32"))] async fn establish(database_url: &str) -> ConnectionResult { let database_url = database_url.to_string(); tokio::task::spawn_blocking(move || C::establish(&database_url)) From 7382e39cfb5e9126031c80f215dc385435b78e5e Mon Sep 17 00:00:00 2001 From: Jonathan Alter Date: Thu, 1 May 2025 11:04:16 -0500 Subject: [PATCH 2/2] relax trait bound for postgres try_from_client_and_connection tokio_postgres::Socket is not supported for wasm32-unknown-unknown target. tokio_postgres, additionally, may return a Connection type whose first bound is not a tokio_postgres::Socket. Accordingly, let's relax the bounds on try_from_client_and_connection so that we match the loosest type that may be returned by tokio_postgres's connection methods, which enables try_from_client_and_connection to work for a wasm32-unknown-unknown target. --- src/pg/mod.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/pg/mod.rs b/src/pg/mod.rs index 127914c..ab8c530 100644 --- a/src/pg/mod.rs +++ b/src/pg/mod.rs @@ -29,6 +29,7 @@ use futures_util::TryFutureExt; use futures_util::{Future, FutureExt, StreamExt}; use std::collections::{HashMap, HashSet}; use std::sync::Arc; +use tokio::io::{AsyncRead, AsyncWrite}; use tokio::sync::broadcast; use tokio::sync::oneshot; use tokio::sync::Mutex; @@ -397,13 +398,13 @@ impl AsyncPgConnection { /// Constructs a new `AsyncPgConnection` from an existing [`tokio_postgres::Client`] and /// [`tokio_postgres::Connection`] - #[cfg(not(target_arch = "wasm32"))] - pub async fn try_from_client_and_connection( + pub async fn try_from_client_and_connection( client: tokio_postgres::Client, - conn: tokio_postgres::Connection, + conn: tokio_postgres::Connection, ) -> ConnectionResult where - S: tokio_postgres::tls::TlsStream + Unpin + Send + 'static, + S: AsyncRead + AsyncWrite + Unpin + Send + 'static, + T: tokio_postgres::tls::TlsStream + Unpin + Send + 'static, { let (error_rx, shutdown_tx) = drive_connection(conn); @@ -879,15 +880,15 @@ async fn drive_future( } } -#[cfg(not(target_arch = "wasm32"))] -fn drive_connection( - conn: tokio_postgres::Connection, +fn drive_connection( + conn: tokio_postgres::Connection, ) -> ( broadcast::Receiver>, oneshot::Sender<()>, ) where - S: tokio_postgres::tls::TlsStream + Unpin + Send + 'static, + S: AsyncRead + AsyncWrite + Unpin + Send + 'static, + T: tokio_postgres::tls::TlsStream + Unpin + Send + 'static, { let (error_tx, error_rx) = tokio::sync::broadcast::channel(1); let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel();