Skip to content

Add support for wasm32-unknown-unknown target #232

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
11 changes: 9 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
] }
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Output = ConnectionResult<Self>> + Send;
Comment on lines +152 to 153
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to keep this method in all configuration.
It should be possible to provide an implementation for this for wasm32 as you somehow need to establish a connection there as well, right?


/// Executes the given function inside of a database transaction
Expand Down
1 change: 1 addition & 0 deletions src/mysql/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl AsyncConnection for AsyncMysqlConnection {

type TransactionManager = AnsiTransactionManager;

#[cfg(not(target_arch = "wasm32"))]
async fn establish(database_url: &str) -> diesel::ConnectionResult<Self> {
let mut instrumentation = DynInstrumentation::default_instrumentation();
instrumentation.on_connection_event(InstrumentationEvent::start_establish_connection(
Expand Down
27 changes: 21 additions & 6 deletions src/pg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -161,6 +162,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<Self> {
let mut instrumentation = DynInstrumentation::default_instrumentation();
instrumentation.on_connection_event(InstrumentationEvent::start_establish_connection(
Expand Down Expand Up @@ -396,12 +398,13 @@ impl AsyncPgConnection {

/// Constructs a new `AsyncPgConnection` from an existing [`tokio_postgres::Client`] and
/// [`tokio_postgres::Connection`]
pub async fn try_from_client_and_connection<S>(
pub async fn try_from_client_and_connection<S, T>(
client: tokio_postgres::Client,
conn: tokio_postgres::Connection<tokio_postgres::Socket, S>,
conn: tokio_postgres::Connection<S, T>,
) -> ConnectionResult<Self>
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);

Expand Down Expand Up @@ -877,18 +880,20 @@ async fn drive_future<R>(
}
}

fn drive_connection<S>(
conn: tokio_postgres::Connection<tokio_postgres::Socket, S>,
fn drive_connection<S, T>(
conn: tokio_postgres::Connection<S, T>,
) -> (
broadcast::Receiver<Arc<tokio_postgres::Error>>,
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();

#[cfg(not(target_arch = "wasm32"))]
tokio::spawn(async move {
match futures_util::future::select(shutdown_rx, conn).await {
Either::Left(_) | Either::Right((Ok(_), _)) => {}
Expand All @@ -898,6 +903,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));
}
}
});

Comment on lines +906 to +915
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the only difference here to the tokio::spawn call above is the name of the spawn function we maybe could refactor this to something like that to minimize code duplication:

let background_future = 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));
            }
        }
};
#[cfg(not(target_arch = "wasm32"))]
tokio::spawn(background_future);
#[cfg(target_arch = "wasm32")]
wasm_bindgen_futures::spawn_local(background_future);

(error_rx, shutdown_tx)
}

Expand Down
1 change: 1 addition & 0 deletions src/pooled_connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ where
type TransactionManager =
PoolTransactionManager<<C::Target as AsyncConnection>::TransactionManager>;

#[cfg(not(target_arch = "wasm32"))]
async fn establish(_database_url: &str) -> diesel::ConnectionResult<Self> {
Err(diesel::result::ConnectionError::BadConnection(
String::from("Cannot directly establish a pooled connection"),
Expand Down
1 change: 1 addition & 0 deletions src/sync_connection_wrapper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ where
type Backend = <C as Connection>::Backend;
type TransactionManager = SyncTransactionManagerWrapper<<C as Connection>::TransactionManager>;

#[cfg(not(target_arch = "wasm32"))]
async fn establish(database_url: &str) -> ConnectionResult<Self> {
let database_url = database_url.to_string();
tokio::task::spawn_blocking(move || C::establish(&database_url))
Expand Down
Loading