1
0
Fork 0

await the mutex in db_run and use block_in_place for it's contents

Dieser Commit ist enthalten in:
Daniel García 2021-11-22 00:01:23 +01:00
Ursprung 19b8388950
Commit cad0dcbed1
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: FC8A7D14C3CD543A

Datei anzeigen

@ -206,72 +206,31 @@ macro_rules! db_run {
// Different code for each db // Different code for each db
( $conn:ident: $( $($db:ident),+ $body:block )+ ) => {{ ( $conn:ident: $( $($db:ident),+ $body:block )+ ) => {{
#[allow(unused)] use diesel::prelude::*; #[allow(unused)] use diesel::prelude::*;
#[allow(unused)] use crate::db::FromDb;
// It is important that this inner Arc<Mutex<>> (or the OwnedMutexGuard
// derived from it) never be a variable on the stack at an await point,
// where Drop might be called at any time. This causes (synchronous)
// Drop to be called from asynchronous code, which some database
// wrappers do not or can not handle.
let conn = $conn.conn.clone(); let conn = $conn.conn.clone();
let mut conn = conn.lock_owned().await;
// Since connection can't be on the stack in an async fn during an match conn.as_mut().expect("internal invariant broken: self.connection is Some") {
// await, we have to spawn a new blocking-safe thread...
/*
run_blocking(move || {
// And then re-enter the runtime to wait on the async mutex, but in
// a blocking fashion.
let mut conn = tokio::runtime::Handle::current().block_on(conn.lock_owned());
let conn = conn.as_mut().expect("internal invariant broken: self.connection is Some");
*/
let mut __conn_mutex = conn.try_lock_owned().unwrap();
let conn = __conn_mutex.as_mut().unwrap();
match conn {
$($( $($(
#[cfg($db)] #[cfg($db)]
crate::db::DbConnInner::$db($conn) => { crate::db::DbConnInner::$db($conn) => {
paste::paste! { paste::paste! {
#[allow(unused)] use crate::db::[<__ $db _schema>]::{self as schema, *}; #[allow(unused)] use crate::db::[<__ $db _schema>]::{self as schema, *};
#[allow(unused)] use [<__ $db _model>]::*; #[allow(unused)] use [<__ $db _model>]::*;
#[allow(unused)] use crate::db::FromDb;
} }
/* tokio::task::block_in_place(move || { $body }) // Run blocking can't be used due to the 'static limitation, use block_in_place instead
// Since connection can't be on the stack in an async fn during an
// await, we have to spawn a new blocking-safe thread...
run_blocking(move || {
// And then re-enter the runtime to wait on the async mutex, but in
// a blocking fashion.
let mut conn = tokio::runtime::Handle::current().block_on(async {
conn.lock_owned().await
});
let conn = conn.as_mut().expect("internal invariant broken: self.connection is Some");
f(conn)
}).await;*/
$body
}, },
)+)+ )+)+
} }
// }).await
}}; }};
( @raw $conn:ident: $( $($db:ident),+ $body:block )+ ) => {{ ( @raw $conn:ident: $( $($db:ident),+ $body:block )+ ) => {{
#[allow(unused)] use diesel::prelude::*; #[allow(unused)] use diesel::prelude::*;
#[allow(unused)] use crate::db::FromDb;
// It is important that this inner Arc<Mutex<>> (or the OwnedMutexGuard
// derived from it) never be a variable on the stack at an await point,
// where Drop might be called at any time. This causes (synchronous)
// Drop to be called from asynchronous code, which some database
// wrappers do not or can not handle.
let conn = $conn.conn.clone(); let conn = $conn.conn.clone();
let mut conn = conn.lock_owned().await;
// Since connection can't be on the stack in an async fn during an
// await, we have to spawn a new blocking-safe thread...
run_blocking(move || {
// And then re-enter the runtime to wait on the async mutex, but in
// a blocking fashion.
let mut conn = tokio::runtime::Handle::current().block_on(conn.lock_owned());
match conn.as_mut().expect("internal invariant broken: self.connection is Some") { match conn.as_mut().expect("internal invariant broken: self.connection is Some") {
$($( $($(
#[cfg($db)] #[cfg($db)]
@ -279,14 +238,12 @@ macro_rules! db_run {
paste::paste! { paste::paste! {
#[allow(unused)] use crate::db::[<__ $db _schema>]::{self as schema, *}; #[allow(unused)] use crate::db::[<__ $db _schema>]::{self as schema, *};
// @ RAW: #[allow(unused)] use [<__ $db _model>]::*; // @ RAW: #[allow(unused)] use [<__ $db _model>]::*;
#[allow(unused)] use crate::db::FromDb;
} }
$body tokio::task::block_in_place(move || { $body }) // Run blocking can't be used due to the 'static limitation, use block_in_place instead
}, },
)+)+ )+)+
} }
}).await
}}; }};
} }