Iron framework for Sharing data in every request issue


#1

I have a struct named App, and i want to make it to share in every request. So i use persistent::Read struct

to store the share data(App), and use middleware::chain to link the data. Then i can use share content by

request.get::<Read>().unwrap().

My issue is when i add a field in App, named pool, type is

Arc<r2d2::Pool<PostgresConnectionManager>>. 

the compiler occur error.


// App struct
pub struct App {
    pool: Arc<r2d2::Pool<PostgresConnectionManager>>,
}

impl Key for App { type Value = App; }



// link detail
let mut chain = Chain::new(self.router);
chain.link(Read::<App>::both(self.app));


// use share data  in every request
let app = request.get::<Read<App>>().unwrap();

the error is

src/main.rs:63:5: 63:53 error: the trait bound `r2d2_postgres::PostgresConnectionManager: r2d2::ManageConnection` is not satisfied [E0277]
src/main.rs:63     pool: Arc<r2d2::Pool<PostgresConnectionManager>>,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:63:5: 63:53 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:63:5: 63:53 note: required by `r2d2::Pool`
src/main.rs:66:6: 66:9 error: the trait bound `r2d2_postgres::PostgresConnectionManager: r2d2::ManageConnection` is not satisfied [E0277]
src/main.rs:66 impl Key for App { type Value = App; }
                    ^~~
src/main.rs:66:6: 66:9 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `alloc::arc::ArcInner<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::marker::PhantomData<alloc::arc::ArcInner<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::ptr::Shared<alloc::arc::ArcInner<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::sync::Arc<r2d2::SharedPool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `r2d2::Pool<r2d2_postgres::PostgresConnectionManager>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `alloc::arc::ArcInner<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::marker::PhantomData<alloc::arc::ArcInner<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::ptr::Shared<alloc::arc::ArcInner<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `std::sync::Arc<r2d2::Pool<r2d2_postgres::PostgresConnectionManager>>`
src/main.rs:66:6: 66:9 note: required because of the requirements on the impl of `std::marker::Reflect` for `App`
src/main.rs:66:6: 66:9 note: required by `iron::typemap::Key`
src/main.rs:89:5: 91:6 error: the trait bound `r2d2_postgres::PostgresConnectionManager: r2d2::ManageConnection` is not satisfied [E0277]
src/main.rs:89     pub fn conn(&self) -> Result<Connection, Error> {
src/main.rs:90         Ok(try!(self.pool.get()))
src/main.rs:91     }
src/main.rs:89:5: 91:6 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:89:5: 91:6 note: required by `r2d2::PooledConnection`


#2

Have you tried this without the Arc? I think Pool is already Send + Sync, and I think Persistent wraps types (in this case App) in an Arc for you.