Hello,
I'm new to Rust and need some help
I'm trying to implement a web server which gets data from a database. As a web server I use Axum (which uses Tokio as its async runtime) and for getting data from the database I want to use Diesel.
As Diesel is blocking I researched how to use it in the async context of Axum. I found out about tokio::task::spawn_blocking
and the crate deadpool
(as well as deadpool_diesel
). By using tokio::task::spawn_blocking
I already got a small performance increase (in comparison to simply using Diesel in my Axum handler), but using deadpool_diesel
I got an even bigger performance boost. Now I'd like to combine both solutions but run into the following issue:
#[tokio::main]
async fn main() {
let manager = Manager::new("postgres://db_user:db_password@localhost:5432/db", Runtime::Tokio1);
let pool = Pool::builder(manager)
.max_size(10)
.build()
.unwrap();
let router = Router::new()
.route("/", get(get_posts))
.layer(Extension(pool));
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(router.into_make_service())
.await
.unwrap();
}
#[debug_handler]
async fn get_posts(
Extension(pool): Extension<Pool>
) -> String {
// Import
use self::schema::posts;
let conn_obj = pool.get().await.unwrap();
let posts = conn_obj.interact(|conn| {
let posts = task::spawn_blocking(move || {
let posts1: Vec<Post> = posts::dsl::posts
.limit(8)
.load::<Post>(conn)
.expect("Error loading posts");
posts1
});
posts
}).await.expect("error 1").await.expect("error 2");
// Return
serde_json::to_string(&posts).expect("error 3")
}
I get the following error:
error[E0521]: borrowed data escapes outside of closure
--> diesel-deadpool-spawn-blocking/src/main.rs:45:21
|
44 | let posts = conn_obj.interact(|conn| {
| ----
| |
| `conn` is a reference that is only valid in the closure body
| has type `&'1 mut PgConnection`
45 | let posts = task::spawn_blocking(move || {
| _____________________^
46 | | let posts1: Vec<Post> = posts::dsl::posts
47 | | .limit(8)
48 | | .load::<Post>(conn)
49 | | .expect("Error loading posts");
50 | | posts1
51 | | });
| | ^
| | |
| |__________`conn` escapes the closure body here
| argument requires that `'1` must outlive `'static`
For more information about this error, try `rustc --explain E0521`.
I understand that the lifetime of the conn
variable is the problem here, but I don't know how to get the actual PgConnection
object in a different way from the connection pool.
Any help is very much appreciated. Thanks in advance