diff --git a/Cargo.lock b/Cargo.lock index 5b98d3e..b9cdc20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -357,7 +357,7 @@ dependencies = [ [[package]] name = "diesel-async" -version = "0.1.0" +version = "0.1.1" dependencies = [ "async-trait", "bb8", @@ -369,6 +369,7 @@ dependencies = [ "mobc", "mysql_async", "mysql_common", + "scoped-futures", "tokio", "tokio-postgres", ] @@ -519,9 +520,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" dependencies = [ "futures-channel", "futures-core", @@ -534,9 +535,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", "futures-sink", @@ -544,15 +545,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-executor" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" dependencies = [ "futures-core", "futures-task", @@ -561,15 +562,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-macro" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" dependencies = [ "proc-macro2", "quote", @@ -578,15 +579,15 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-timer" @@ -596,9 +597,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-channel", "futures-core", @@ -1422,6 +1423,16 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "scoped-futures" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655305227172f0178a34e02386c3b72e9c0d247a3b5087442540dbeb74c95c9a" +dependencies = [ + "cfg-if", + "pin-utils", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -1662,9 +1673,21 @@ dependencies = [ "parking_lot", "pin-project-lite", "socket2", + "tokio-macros", "winapi", ] +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tokio-native-tls" version = "0.3.0" diff --git a/Cargo.toml b/Cargo.toml index 2e864b5..c2b3817 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ mysql_common = {version = "0.29.0", optional = true} bb8 = {version = "0.8", optional = true} deadpool = {version = "0.9", optional = true} mobc = {version = "0.7", optional = true} +scoped-futures = {version = "0.1", features = ["std"]} [dev-dependencies] tokio = {version = "1.12.0", features = ["rt", "macros", "rt-multi-thread"]} diff --git a/src/lib.rs b/src/lib.rs index 77dd137..1df22d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,9 +70,11 @@ use diesel::backend::Backend; use diesel::query_builder::{AsQuery, QueryFragment, QueryId}; use diesel::row::Row; use diesel::{ConnectionResult, QueryResult}; -use futures::future::BoxFuture; use futures::{Future, Stream}; +pub use scoped_futures; +use scoped_futures::ScopedBoxFuture; + #[cfg(feature = "mysql")] mod mysql; #[cfg(feature = "postgres")] @@ -180,7 +182,7 @@ where /// ```rust /// # include!("doctest_setup.rs"); /// use diesel::result::Error; - /// use futures::FutureExt; + /// use scoped_futures::ScopedFutureExt; /// /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { @@ -200,7 +202,7 @@ where /// assert_eq!(vec!["Sean", "Tess", "Ruby"], all_names); /// /// Ok(()) - /// }.boxed()).await?; + /// }.scope_boxed()).await?; /// /// conn.transaction::<(), _, _>(|conn| async move { /// diesel::insert_into(users) @@ -214,18 +216,18 @@ where /// // If we want to roll back the transaction, but don't have an /// // actual error to return, we can return `RollbackTransaction`. /// Err(Error::RollbackTransaction) - /// }.boxed()).await; + /// }.scope_boxed()).await; /// /// let all_names = users.select(name).load::(conn).await?; /// assert_eq!(vec!["Sean", "Tess", "Ruby"], all_names); /// # Ok(()) /// # } /// ``` - async fn transaction(&mut self, callback: F) -> Result + async fn transaction<'a, R, E, F>(&mut self, callback: F) -> Result where - F: FnOnce(&mut Self) -> BoxFuture> + Send, - E: From + Send, - R: Send, + F: for<'r> FnOnce(&'r mut Self) -> ScopedBoxFuture<'a, 'r, Result> + Send + 'a, + E: From + Send + 'a, + R: Send + 'a, { Self::TransactionManager::transaction(self, callback).await } diff --git a/src/pg/mod.rs b/src/pg/mod.rs index 825c38c..934a75d 100644 --- a/src/pg/mod.rs +++ b/src/pg/mod.rs @@ -271,7 +271,7 @@ impl AsyncPgConnection { /// /// ```rust /// # include!("../doctest_setup.rs"); - /// # use futures::FutureExt; + /// # use scoped_futures::ScopedFutureExt; /// # /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() { @@ -285,7 +285,7 @@ impl AsyncPgConnection { /// .read_only() /// .serializable() /// .deferrable() - /// .run(|conn| async move { Ok(()) }.boxed()) + /// .run(|conn| async move { Ok(()) }.scope_boxed()) /// .await /// # } /// ``` diff --git a/src/pg/transaction_builder.rs b/src/pg/transaction_builder.rs index 05b5869..fa52dfa 100644 --- a/src/pg/transaction_builder.rs +++ b/src/pg/transaction_builder.rs @@ -3,7 +3,7 @@ use diesel::backend::Backend; use diesel::pg::Pg; use diesel::query_builder::{AstPass, QueryBuilder, QueryFragment}; use diesel::QueryResult; -use futures::future::BoxFuture; +use scoped_futures::ScopedBoxFuture; /// Used to build a transaction, specifying additional details. /// @@ -283,10 +283,11 @@ where /// the original error will be returned, otherwise the error generated by the rollback /// will be returned. In the second case the connection should be considered broken /// as it contains a uncommitted unabortable open transaction. - pub async fn run(&mut self, f: F) -> Result + pub async fn run<'b, T, E, F>(&mut self, f: F) -> Result where - F: FnOnce(&mut C) -> BoxFuture> + Send, - E: From, + F: for<'r> FnOnce(&'r mut C) -> ScopedBoxFuture<'b, 'r, Result> + Send + 'a, + T: 'b, + E: From + 'b, { let mut query_builder = ::QueryBuilder::default(); self.to_sql(&mut query_builder, &Pg)?; diff --git a/src/run_query_dsl/mod.rs b/src/run_query_dsl/mod.rs index f7cb98b..eff30b7 100644 --- a/src/run_query_dsl/mod.rs +++ b/src/run_query_dsl/mod.rs @@ -96,7 +96,7 @@ pub mod methods { U: Send, T: AsQuery + Send, T::SqlType: CompatibleType, - U: FromSqlRow + Send + 'static, + U: FromSqlRow + Send, DB: QueryMetadata, { type LoadFuture = futures::future::MapOk< @@ -115,13 +115,12 @@ pub mod methods { where Conn: AsyncConnection, U: Send, - DB: Backend + 'static, + DB: Backend, T: AsQuery + Send + 'query, T::Query: QueryFragment + QueryId + Send + 'query, T::SqlType: CompatibleType, - U: FromSqlRow + Send + 'static, + U: FromSqlRow + Send, DB: QueryMetadata, - ST: 'static, { fn internal_load<'conn>( self, @@ -142,9 +141,8 @@ pub mod methods { where S: Stream> + Send + 's, R: diesel::row::Row<'a, DB> + 's, - DB: Backend + 'static, - U: FromSqlRow + 'static, - ST: 'static, + DB: Backend, + U: FromSqlRow, { stream.map(map_row_helper::<_, DB, U, ST>) } diff --git a/src/transaction_manager.rs b/src/transaction_manager.rs index eb01cc6..d588f95 100644 --- a/src/transaction_manager.rs +++ b/src/transaction_manager.rs @@ -1,6 +1,6 @@ use diesel::result::Error; use diesel::QueryResult; -use futures::future::BoxFuture; +use scoped_futures::ScopedBoxFuture; use std::borrow::Cow; use std::num::NonZeroU32; @@ -50,9 +50,9 @@ pub trait TransactionManager: Send { /// /// Each implementation of this function needs to fulfill the documented /// behaviour of [`AsyncConnection::transaction`] - async fn transaction(conn: &mut Conn, callback: F) -> Result + async fn transaction<'a, F, R, E>(conn: &mut Conn, callback: F) -> Result where - F: FnOnce(&mut Conn) -> BoxFuture> + Send, + F: for<'r> FnOnce(&'r mut Conn) -> ScopedBoxFuture<'a, 'r, Result> + Send + 'a, E: From + Send, R: Send, { diff --git a/tests/lib.rs b/tests/lib.rs index e17b2eb..ddc6d80 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,7 +1,7 @@ use diesel::prelude::{ExpressionMethods, OptionalExtension, QueryDsl}; use diesel::QueryResult; use diesel_async::*; -use futures::FutureExt; +use scoped_futures::ScopedFutureExt; use std::fmt::Debug; use std::pin::Pin; @@ -31,7 +31,7 @@ async fn transaction_test(conn: &mut TestConnection) -> QueryResult<()> { assert_eq!(count, 3); Ok(()) } - .boxed() + .scope_boxed() }) .await; assert!(res.is_ok());