-
-
Notifications
You must be signed in to change notification settings - Fork 109
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
Update to async/await #37
Conversation
I haven't been paying a lot of attention to this so please let me know when it's ready for me to look at. |
Sure, that's what I was planning on. I've got all but one test passing in the base library, will try to redo the commits to improve review ability. |
One open question is if the closure-style |
(This is now passing all the tests in the base library. If you've got time for an early look, that might be helpful. I'll see if I can get postgres and redis working, too.) |
I am in favor of the drop-based interface. The |
Okay, I think this is a more or less minimal complete conversion to async/await. That is:
Notably, for redis this still depends on an in-progress PR branch rather than a released alpha (unlike with tokio-postgres). I think there are still improvements that can be made, but I didn't want to make these commits even larger than they already are. @khuey please review and think about the closure vs guard issue from #37 (comment). |
The closure thing exists to make it (nearly) statically impossible to "leak" connections. I'll think about it some more but I would be a bit hesitant to give that up. |
We could potentially offer both. I do think the ergonomics of the guard type are a bit nicer. (In either case, don't need to block this PR on this question.) |
@khuey do you see people in practice leaking connections with something like r2d2? https://docs.rs/r2d2/0.8.6/r2d2/struct.PooledConnection.html |
I haven't seen people leaking connections in practice with r2d2 but I also haven't been looking at how people use r2d2. In general I prefer statically checking correctness, which the closure type does (and the lack of static checking of correctness is one of my big gripes with tokio). That said, I'm not married to it. I'm not sure when I'm going to have time to look at this PR but I'm not going to reject it just for that. |
(This PR does not change that aspect of the API -- we can do that separately.) |
Great. |
You can still have that style of API if you'd like - just pass a |
I'm only a user of the library and not sure of any of the technical considerations for doing so, but I would vastly prefer a drop-based interface if it's at all possible. If this were to instead require the closure style I'd probably just use tokio-resource-pool instead, since I believe they have implemented the drop-style. Also, if I recall correctly, I believe whether or not this API is made drop-based is a large consideration on whether or not it will be used for the Rocket web framework. It would integrate much more effectively if drop-based. |
The comment about using a mut reference for the best of both worlds is
pretty compelling.
…On Tue, Nov 5, 2019, 7:21 AM githubaccount624 ***@***.***> wrote:
I'm only a user of the library and not sure of any of the technical
considerations for doing so, but I would vastly prefer a drop-based
interface if it's at all possible. If this were to instead require the
closure style I'd probably just use tokio-resource-pool instead, since I
believe they have implemented the drop-style. Also, if I recall correctly,
I believe whether or not this API is made drop-based is a large
consideration on whether or not it will be used for the Rocket web
framework. It would integrate much more effectively if drop-based.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#37>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACPSBBK7A6W6Y3PNXKZBPDQSGFRFANCNFSM4JADDOSQ>
.
|
I'm not sure if it's a bug, but if rustc 1.40.0-nightly (b520af6fd 2019-11-03) [dependencies]
async-trait = "0.1.17"
bb8 = { git = "https://github.com/djc/bb8", branch = "async-await" }
env_logger = "0.7.1"
log = "0.4.8"
tokio = { package = "tokio", version = "0.2.0-alpha.6" } use async_trait::async_trait;
use bb8::ManageConnection;
use env_logger::Env;
use log::{debug, error};
use std::io::{Error, ErrorKind};
struct Connection {}
struct Manager {}
#[async_trait]
impl ManageConnection for Manager {
type Connection = Connection;
type Error = Error;
async fn connect(&self) -> Result<Self::Connection, Self::Error> {
debug!("connect()");
Ok(Connection {})
}
async fn is_valid(
&self,
conn: Self::Connection,
) -> Result<Self::Connection, (Self::Error, Self::Connection)> {
debug!("is_valid()");
Err((Error::new(ErrorKind::Other, "oh no!"), conn))
}
fn has_broken(&self, _conn: &mut Self::Connection) -> bool {
debug!("has_broken()");
false
}
}
#[tokio::main]
async fn main() -> Result<(), Error> {
let env = Env::default().filter_or("RUST_LOG", "debug");
env_logger::init_from_env(env);
let pool = bb8::Builder::new().max_size(1).build(Manager {}).await?;
for i in 1..=2 {
debug!("try: {}", i);
if let Err(e) = pool
.run(|c: Connection| {
async {
debug!("use connection");
Ok::<(u8, Connection), (Error, Connection)>((1, c))
}
})
.await
{
error!("err pool.run: {}", e);
}
}
Ok(())
} log
|
Thanks for trying it! Could you please turn this into a commit that adds a test case? That makes it easier to work on and make sure we don't regress that case going forward. |
Done #1 |
test_is_valid_once()
@bbigras are you sure the test is right? The condition in |
@djc in the test, I wanted The |
Ah, ok. |
I just realized in the shower that it wont work since the connection whould be new after a fail. So it will always fail. I should use an atomic int or something like that. |
Done. #2 |
One thing to note: futures 0.3 have been release after Rust 1.39 got released |
Right, but there is no tokio (alpha) release that can work with futures 0.3 yet. |
@djc are you interested in mentoring for the drop-based interface changes? |
@elpiel sure, if you want to implement it I'm happy to answer your questions and/or give you guidance. |
src/lib.rs
Outdated
Err((_, conn)) => { | ||
let clone = inner.clone(); | ||
let locked = clone.internals.lock().await; | ||
let _ = drop_connections(&inner, locked, vec![conn]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing an .await
src/lib.rs
Outdated
|
||
let mut locked = inner.internals.lock().await; | ||
if broken { | ||
let _ = drop_connections(&inner, locked, vec![conn]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing an .await
@khuey is there anything I can do to make this easier to review? I'm also okay with becoming co-maintainer if you'd like. As it is, I find myself not very motivated to make further changes until I get some feedback on the progress here. :) |
Reviewing this is on my todo list for this weekend. |
I have a couple small concerns that I'll file followup issues on but nothing that I think should block landing this. Thank you very much for contributing this and for your patience. |
@khuey thanks for merging, no problem with the waiting -- I know how it goes. Feel free to cc me on any follow-up issues you file. |
This passes the bb8 tests on beta. postgres and redis don't compile yet, I still have figure out how to deal with
Unpin
ness.