首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >铁锈-无法从火箭状态访问r2d2池连接

铁锈-无法从火箭状态访问r2d2池连接
EN

Stack Overflow用户
提问于 2021-09-01 20:29:32
回答 1查看 782关注 0票数 0

我现在正在学习锈蚀和火箭

使用锈蚀1.54.0+Rocket 0.5.0_rc1+柴油机1.4.7 + r2d2 0.8.9

我用r2d2创建了一个DB连接池。我想共享请求/路由之间的连接池,为此我尝试使用火箭管理状态()。https://rocket.rs/v0.5-rc/guide/state/#managed-state

我创建了一个DB连接池,将它保存在状态上,但是当我试图从路由访问那个DB连接池时。我在同一行上有两个错误

Cell<i32> cannot be shared between threads safely

RefCell<HashMap<StatementCacheKey<Pg>, pg::connection::stmt::Statement>> cannot be shared between threads safely

这是我的代码

代码语言:javascript
复制
pub async fn establish_pooled_connection() -> Result<PooledConnection<ConnectionManager<PgConnection>>, r2d2_diesel::Error> {
    dotenv().ok();
    let database_url = env::var("DATABASE_URL")
        .expect("DATABASE_URL must be set");
    let manager = ConnectionManager::<PgConnection>::new(&database_url);
    let pool = r2d2::Pool::builder().build(manager).expect("Failed to create pool.");
    let conn = pool.clone().get().unwrap();
    Ok(conn)
}

struct DBPool{
    db_pool: PooledConnection<ConnectionManager<PgConnection>>
}

#[rocket::main]
async fn main() {
  
    let pool = establish_pooled_connection();    
    rocket::build()
        .mount("/",routes![callapi])
        .manage(DBPool{db_pool: pool})
        .launch()
        .await.ok();       
}

#[post("/callapi", data = "<request>")]
async fn callapi(request: RequestAPI<'_>, _dbpool: &State<DBPool>) -> Json<models::api_response::ApiResponse> {
......

错误用于此参数。

_dbpool: &State<DBPool>

提前感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-06 21:26:56

最后,我终于成功了。

我主要使用这个GitHub回购作为基本https://github.com/practical-rust-web-development/mystore/tree/v1.1,回购使用Actix,但我使用火箭。

我认为我的主要错误理解是,基本的PostgreSQL连接是一个PGConnection,从池中得到的是一个PGPooledConnection,它的末尾是相同的。

这是我的代码

db_connection.rs

代码语言:javascript
复制
use diesel::pg::PgConnection;
use dotenv::dotenv;
use std::env;
use diesel::r2d2::{ Pool, PooledConnection, ConnectionManager, PoolError };

pub type PgPool = Pool<ConnectionManager<PgConnection>>;
pub type PgPooledConnection = PooledConnection<ConnectionManager<PgConnection>>;

//Connects to Postgres and call init pool
pub fn establish_connection() -> PgPool {
    dotenv().ok();

    let database_url = env::var("DATABASE_URL")
        .expect("DATABASE_URL must be set");
    init_pool(&database_url).expect("Failed to create pool")
}


//Creates a default R2D2 Postgres DB Pool
fn init_pool(database_url: &str) -> Result<PgPool, PoolError> {
    let manager = ConnectionManager::<PgConnection>::new(database_url);
    Pool::builder().build(manager)
}


//this functions returns a connection from the Pool
pub fn pg_pool_handler(pool: &PgPool) -> Result<PgPooledConnection, PoolError> {
    let _pool = pool.get().unwrap();
    Ok(_pool)
}

main.rs

代码语言:javascript
复制
mod db_connection;
use db_connection::{PgPool};

#[rocket::main]
async fn main() {
    rocket::build()
        .mount("/API",routes![demo])
        .manage(db_connection::establish_connection()) //here is where you pass the pool to Rocket state.
        .launch()
        .await.ok();       
}

#[post("/demo", data = "<request>")]
async fn demo _dbpool: &State<PgPool>) -> Json<models::Response> {

let connection = db_connection::pg_pool_handler(_dbpool).unwrap();

let results = users.limit(1)
        .load::<User>(&connection)
        .expect("Error loading users");
........

这是基本的代码,代码可以改进,以更好的方式处理错误。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69020229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档