2

テストを作成する際に、リクエストに接続を挿入して、テスト ケース全体をトランザクションでラップできるようにしたいと考えています (テスト ケースに複数のリクエストがある場合でも)。

BeforeMiddlewareテストケースでリンクして接続を挿入できるを使用してこれを実行しようとしました。

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(())
    }
}

ただし、これを実行しようとするとコンパイル エラーが発生します。

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が、ディーゼルを使い続けたいと思います。

4

2 に答える 2

7

この答えは確かに問題を解決しますが、最適ではありません。前述のように、スレッドセーフではないため、単一の接続を共有することはできません。ただし、これを でラップすると、Mutexスレッドセーフになりますが、すべてのサーバー スレッドが1 つの接続を使用することになります。代わりに、接続プールを使用します。

これは、r2d2およびr2d2-dieselクレートで実現できます。これにより、必要に応じて複数の接続が確立され、可能な場合はスレッドセーフな方法でそれらが再利用されます。

于 2016-08-17T10:55:28.890 に答える