-
-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Returning connection from a pool without pool explicitly in scope #11
Comments
You can do this with a small amount of trickiness: struct SelfContainedConnection<M, T> {
// must be in this order to ensure the connection drops before the pool
conn: PooledConnection<'static, T>,
pool: Arc<Pool<M>>,
}
impl<M, T> SelfContainedConnection<M, T> where M: ConnectionManager, T: ConnectionManager::Connection {
pub fn new(pool: &Arc<Pool>) -> Result<SelfContainedConnection, GetTimeout> {
let conn = try!(pool.get());
let pool = pool.clone();
Ok(SelfContainedConnection {
conn: unsafe { mem::transmute(conn) },
pool: pool
})
}
}
impl<M, T> Deref for SelfContainedConnection<M, T> {
type Target = T;
fn deref(&self) -> &T {
&*self.conn
}
} We define a new smart pointer that holds both the original PooledConnection pointer as well as a reference to the pool to make sure it stays alive. |
Which version of rust does that work on @sfackler? On nightly I get:
I rewrote that with explicit Connection where needed and dropped T:
But that still fails with:
|
I'm not sure it works on any version - I wrote it from memory. That transmute error can be worked around, but it requires more unsafe hackery than I'm really comfortable with. The request for a lifetime-unrestricted let pool: &Arc<Pool<M>> = my_pool;
let conn = Pool::get_arc(pool.clone()).unwrap(); // conn has a 'static lifetime I can publish the update to crates.io if this seems reasonable to you. |
@sfackler yeah crates.io currently has similar code to get a |
Published v0.5.8 with |
cc me, this is an important API consideration for iron |
Thoughts? |
I suspect that the "overhead" from using an This pattern is in use elsewhere, though, for example in Servo's work stealing deque. The |
A somewhat related question is how sharing across threads should be handled. Right now, you put the Pool into an Arc, but Pool could impl Clone itself. This seems a bit weird to me, but it does appear to be what Servo's BufferedPool does. |
Just tested I'm not sure what the last comment meant. Something like |
Right now, if you want to share a let pool = Arc::new(Pool::new(...));
let pool2 = pool.clone();
thread::spawn(move || {
let pool = pool2;
// use the pool
});
// use the other pool We could change let pool = Pool::new(...);
let pool2 = pool.clone();
thread::spawn(move || {
let pool = pool2;
// use the pool
});
// use the other pool Pool itself is just a bare wrapper around an |
I've made the changes discussed: I'll be releasing those changes and some others as v0.6 in a couple days probably. |
v0.6.0's been released. |
I'm not very experienced in rust yet, so I'm sorry for potential misunderstanding ;)
I ran into an issue where I'd like to abstract returning a connection from a pool into a function. Basically the original code in Iron request handler is:
and I wanted to make the first two lines just
let connection = get_pool_connection(req);
. This however is not possible unlesspool
is returned along with the connection so it can live for the same time.I was hoping this could be improved by storing an
Rc<Pool>
somewhere in the connection itself. Or maybe there are other ways to allow a function like this to exist:Related SO with the question and answer here: https://stackoverflow.com/questions/30252054/refactoring-messes-up-mutable-borrow-why
The text was updated successfully, but these errors were encountered: