将 Diesel 连接注入 Iron 中间件 [英] Injecting a Diesel connection into an Iron middleware

查看:51
本文介绍了将 Diesel 连接注入 Iron 中间件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在编写我的测试时,我希望能够将连接注入到请求中,以便我可以将整个测试用例包装在一个事务中(即使测试用例中有多个请求).

In writing my tests, I'd like to be able to inject a connection into the request so that I can wrap the entire test case in a transaction (even if there is more than one request in the test case).

我尝试使用 BeforeMiddleware 来做到这一点,我可以将其链接到我的测试用例中以插入连接,例如:

I've attempted to do this using a BeforeMiddleware which I can link in my test cases to insert a connection, as such:

pub type DatabaseConnection = PooledConnection<ConnectionManager<PgConnection>>;

pub struct DatabaseOverride {
    conn: DatabaseConnection,
}

impl BeforeMiddleware for DatabaseOverride {
    fn before(&self, req: &mut Request) -> IronResult<()> {
        req.extensions_mut().entry::<DatabaseOverride>().or_insert(self.conn);
        Ok(())
    }
}

但是,我在尝试执行此操作时遇到了编译错误:

However, I'm encountering a compile error in trying to do this:

error: the trait bound `std::rc::Rc<diesel::pg::connection::raw::RawConnection>: std::marker::Sync` is not satisfied [E0277]
impl BeforeMiddleware for DatabaseOverride {
     ^~~~~~~~~~~~~~~~
help: run `rustc --explain E0277` to see a detailed explanation
note: `std::rc::Rc<diesel::pg::connection::raw::RawConnection>` cannot be shared between threads safely
note: required because it appears within the type `diesel::pg::PgConnection`
note: required because it appears within the type `r2d2::Conn<diesel::pg::PgConnection>`
note: required because it appears within the type `std::option::Option<r2d2::Conn<diesel::pg::PgConnection>>`
note: required because it appears within the type `r2d2::PooledConnection<r2d2_diesel::ConnectionManager<diesel::pg::PgConnection>>`
note: required because it appears within the type `utility::db::DatabaseOverride`
note: required by `iron::BeforeMiddleware`

error: the trait bound `std::cell::Cell<i32>: std::marker::Sync` is not satisfied [E0277]
impl BeforeMiddleware for DatabaseOverride {
     ^~~~~~~~~~~~~~~~
help: run `rustc --explain E0277` to see a detailed explanation
note: `std::cell::Cell<i32>` cannot be shared between threads safely
note: required because it appears within the type `diesel::pg::PgConnection`
note: required because it appears within the type `r2d2::Conn<diesel::pg::PgConnection>`
note: required because it appears within the type `std::option::Option<r2d2::Conn<diesel::pg::PgConnection>>`
note: required because it appears within the type `r2d2::PooledConnection<r2d2_diesel::ConnectionManager<diesel::pg::PgConnection>>`
note: required because it appears within the type `utility::db::DatabaseOverride`
note: required by `iron::BeforeMiddleware`

有没有办法通过柴油的连接来解决这个问题?我在 Github 上找到了几个使用 pg 板条箱来做到这一点的例子,但我想继续使用柴油.

Is there a way around this with diesel's connections? I've found several examples on Github to do this using the pg crate, but I'd like to keep using diesel.

推荐答案

这个答案肯定能解决问题,但是它不是最佳的.如前所述,您不能共享单个连接,因为它不是线程安全的.然而,虽然将其包装在 Mutex 中使其成为线程安全的,但它会强制所有服务器线程使用单个连接.相反,您想使用连接池.

This answer will certainly solve the problem, but it's not optimal. As mentioned, you can't share a single connection as it's not thread safe. However, while wrapping it in a Mutex makes it thread-safe, it would force all the server threads to use a single connection. Instead, you want to use a connection pool.

您可以使用 r2d2r2d2-diesel 板条箱.这将根据需要建立多个连接,并在可能的情况下以线程安全的方式重用它们.

You can accomplish this with the r2d2 and r2d2-diesel crates. This will establish multiple connections as needed, and reuse them when possible in a thread safe manner.

这篇关于将 Diesel 连接注入 Iron 中间件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆