Comments (27)
Try conn.prepare(blahblahblah).compat().then(do_stuff)
?
from bb8.
Okay. Now, with the following function:
async fn try_cmd(mg: Message, mut args: Args, state: Arc<State>) -> Result<()> {
state.postgres.run(|mut conn| {
conn.prepare("SELECT slot_1, slot_2, slot_3 FROM loadouts WHERE user_id = $1")
.compat()
.then(|st| {
let query = conn.query(&st.unwrap(), &[&(mg.author.id.0 as i64)]);
// Work with query
Ok(())
})
});
Ok(())
}
I get the following:
error[E0277]: the trait bound `std::result::Result<(), _>: core::future::future::Future` is not satisfied
--> src/commands/loadout.rs:38:14
|
38 | .then(|st| {
| ^^^^ the trait `core::future::future::Future` is not implemented for `std::result::Result<(), _>`
error[E0277]: the trait bound `futures_util::future::then::Then<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, std::result::Result<(), _>, [closure@src/commands/loadout.rs:38:19: 41:14 conn:_, mg:_]>: futures::future::Future` is not satisfied
--> src/commands/loadout.rs:35:20
|
35 | state.postgres.run(|mut conn| {
| ^^^ the trait `futures::future::Future` is not implemented for `futures_util::future::then::Then<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, std::result::Result<(), _>, [closure@src/commands/loadout.rs:38:19: 41:14 conn:_, mg:_]>`
|
= note: required because of the requirements on the impl of `futures::future::IntoFuture` for `futures_util::future::then::Then<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, std::result::Result<(), _>, [closure@src/commands/loadout.rs:38:19: 41:14 conn:_, mg:_]>`
I'd ultimately want to port this code to async/await if possible. Any suggestions here?
from bb8.
You should probably read https://jsdw.me/posts/rust-asyncawait-preview/. I think rather than using the compat method you should import the futures 0.1 Future
trait and convert only to a new style future at the outermost layer (the state.postgres.run)
from bb8.
Feel free to keep commenting but because this is not actually a bug in bb8 I'm going to close this issue.
from bb8.
@khuey I know this isn't an issue with bb8, but would you have a clue on how to get a solution like async/await
working?
From the guide you mentioned, it says that you can use the tokio::await!()
to convert an old style future to a new stylle future. So I've done something like this:
fn execute(&self, mg: Message, args: Args, state: Arc<State>) {
tokio::run_async(async move {
let mut resp = CommandResponse::new(mg.channel_id.0, state);
await!(resp.text("Testing my Text").execute()).unwrap();
tokio::await!(state.postgres.run(async move |mut conn| {
let stmt = tokio::await!(conn.prepare("SELECT slot_1, slot_2, slot_3 FROM loadouts WHERE user_id = $1"))?;
let query = conn.query(&stmt, &[&(mg.author.id.0 as i64)]);
await!(resp.text("Testing my Text").execute())?;
}))
Ok(())
});
}
However, I am greeted with this error:
error[E0271]: type mismatch resolving `<impl core::future::future::Future as core::future::future::Future>::Output == ()`
--> src/commands/help.rs:27:9
|
27 | tokio::run_async(async move {
| ^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
|
= note: expected type `std::result::Result<(), _>`
found type `()`
= note: required by `tokio::run_async`
error[E0277]: the trait bound `impl core::future::future::Future: tokio::prelude::Future` is not satisfied
--> src/commands/loadout.rs:31:42
|
31 | tokio::await!(state.postgres.run(async move |mut conn| {
| ^^^ the trait `tokio::prelude::Future` is not implemented for `impl core::future::future::Future`
|
= note: required because of the requirements on the impl of `tokio::prelude::IntoFuture` for `impl core::future::future::Future`
error[E0271]: type mismatch resolving `<impl core::future::future::Future as core::future::future::Future>::Output == ()`
--> src/commands/loadout.rs:28:9
|
28 | tokio::run_async(async move {
| ^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
|
= note: expected type `std::result::Result<_, _>`
found type `()`
= note: required by `tokio::run_async`
Am in misinterpreting something here?
from bb8.
You should unwrap
(or actually handle errors) from the await!
and then get rid of the Ok(())
at the end.
from bb8.
Right now, I'm currently at this error.
error[E0277]: the trait bound `impl core::future::future::Future: tokio::prelude::Future` is not satisfied
--> src/commands/loadout.rs:44:34
|
44 | tokio::await!(state.postgres.run(async move |mut conn| {
| ^^^ the trait `tokio::prelude::Future` is not implemented for `impl core::future::future::Future`
|
= note: required because of the requirements on the impl of `tokio::prelude::IntoFuture` for `impl core::future::future::Future`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277
I feel like its something to do with the run()
method not directly returning a future?
from bb8.
postgres.run
wants an old style future, not the async
stuff. I think you can just get rid of the async
keyword there and fix up the return value.
from bb8.
Problem with that being, I want to be able to use the await macro inside, since I have async operations that rely on the result from the query.
from bb8.
Ok, then follow the steps in the article that I linked about converting from a new style future to an old style one?
from bb8.
Well I ended up doing that.
Now I need to fix to return value to what?
from bb8.
Idk, what errors do you have now?
from bb8.
error[E0277]: the trait bound `(): core::future::future::Future` is not satisfied
--> src/commands/loadout.rs:47:10
|
47 | .then(move |st| {
| ^^^^ the trait `core::future::future::Future` is not implemented for `()`
error[E0277]: the trait bound `futures_util::future::then::Then<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, (), [closure@src/commands/loadout.rs:47:15: 49:10 conn:_, mg:_]>: tokio::prelude::Future` is not satisfied
--> src/commands/loadout.rs:44:34
|
44 | tokio::await!(state.postgres.run(move |mut conn| {
| ^^^ the trait `tokio::prelude::Future` is not implemented for `futures_util::future::then::Then<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, (), [closure@src/commands/loadout.rs:47:15: 49:10 conn:_, mg:_]>`
|
= note: required because of the requirements on the impl of `tokio::prelude::IntoFuture` for `futures_util::future::then::Then<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, (), [closure@src/commands/loadout.rs:47:15: 49:10 conn:_, mg:_]>`
error: aborting due to 2 previous errors
This is using the compat() way to be able to return a futures 0.1 future.
from bb8.
And what's in the then
closure?
from bb8.
.then(move |st| {
let query = conn.query(&st.unwrap, [&(mg.author.id.0 as i64)]);
})
from bb8.
The return value of that closure needs to be a future. Also you're not actually calling unwrap
, and you wouldn't need it at all if you used and_then
instead of then
for this closure.
Try something like
.and_then(move |st| {
conn.query(&st, [&(mg.author.id.0 as i64)])
})
from bb8.
@khuey Sorry about the delay,
So this is what we have now:
async fn my_cmd(mg: Message, mut args: Args, state: Arc<State>) -> Result<()> {
let mut resp = CommandResponse::new(mg.channel_id.0, state);
await!(resp.text("Testing my Text").execute())?;
tokio::await!(state.postgres.run(move |mut conn| {
conn.prepare("SELECT slot_1, slot_2, slot_3 FROM loadouts WHERE user_id = $1")
.compat()
.and_then(move |st| {
let query = conn.query(&st, &[&(mg.author.id.0 as i64)]);
})
}));
Ok(())
}
This yields the following:
|
47 | .and_then(move |st| {
| ^^^^^^^^ the trait `core::future::future::Future` is not implemented for `()`
|
= note: required because of the requirements on the impl of `futures_core::future::TryFuture` for `()`
error[E0277]: the trait bound `futures_util::try_future::and_then::AndThen<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, (), [closure@src/commands/loadout.rs:47:19: 49:10 conn:_, mg:_]>: tokio::prelude::Future` is not satisfied
--> src/commands/loadout.rs:44:34
|
44 | tokio::await!(state.postgres.run(move |mut conn| {
| ^^^ the trait `tokio::prelude::Future` is not implemented for `futures_util::try_future::and_then::AndThen<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, (), [closure@src/commands/loadout.rs:47:19: 49:10 conn:_, mg:_]>`
|
= note: required because of the requirements on the impl of `tokio::prelude::IntoFuture` for `futures_util::try_future::and_then::AndThen<futures_util::compat::compat01as03::Compat01As03<tokio_postgres::impls::Prepare>, (), [closure@src/commands/loadout.rs:47:19: 49:10 conn:_, mg:_]>`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.
So if I understand correctly, I have to return a future in the .and_then()
closure as well?
from bb8.
Right. Try something like this:
async fn my_cmd(mg: Message, mut args: Args, state: Arc<State>) -> Result<()> {
let mut resp = CommandResponse::new(mg.channel_id.0, state);
await!(resp.text("Testing my Text").execute())?;
let results = tokio::await!(state.postgres.run(move |mut conn| {
conn.prepare("SELECT slot_1, slot_2, slot_3 FROM loadouts WHERE user_id = $1")
.then(move |r| {
match r {
Ok(st) => {
conn.query(&st, &[&(mg.author.id.0 as i64)])
.then(move |r| {
match r {
Ok(results) => Ok((results, conn)),
Err(e) => {
eprintln!("Got postgres error on query: {}", e);
Err(((), conn))
}
}
})
}
Err(e) => {
eprintln!("Got postgres error on prepare: {}", e);
Err((), conn)
}
}
})
}))?;
println!("My results are {:?}", results);
Ok(())
}
from bb8.
https://github.com/khuey/bb8/blob/master/postgres/examples/static_select.rs has a working example without async/await, btw, if you haven't seen that.
from bb8.
A brief question:
On the error handling for the first prepare statement, why do you return an Err((), conn)
? Won't Rust be expecting a Then with the result of the prepare?
from bb8.
Yeah...it seems like using this library with async/await is going to be much more difficult than I had anticipated.
from bb8.
The basic premise of a the run
function in bb8 is that you "check out" a connection from a pool, do some stuff with it, and return it when you're done. You can see the type signature of run
https://github.com/khuey/bb8/blob/36b635b4741f36af2907fd32fe91b281ca0a2b93/src/lib.rs#L721. run
takes a closure that returns something that implements IntoFuture<Item = (T, M::Connection), Error = (E, M::Connection)>
.
In old style futures Result<T, E>
implements IntoFuture<Item = T, Error = E>
so you'll see that a lot. Operations that can fail but happen synchronously take advantage of this: and_then
and then
combinator closures often produce a Result
instead of a "real" future.
from bb8.
@khuey One thing I don't understand.
What is the Either
enum that you are using and how do I get it?
It doesn't seem to be part of the futures package.
from bb8.
I don't believe that the PostgreSQL example provided even compiles correctly though. :(
from bb8.
Either
comes from https://docs.rs/futures/0.1.25/futures/future/enum.Either.html
If you check out this repository and cargo build --all --examples
that fails?
from bb8.
It doesn't fail, just thought I saw some syntax errors there. I guess not.
from bb8.
However, I noticed that the futures
crate does clash with the futures-preview crate I have installed. Do you know a way to have both installed under different names?
from bb8.
Related Issues (20)
- CI keeps failing HOT 1
- Connection pool hangs if authentication fails HOT 6
- Time taken to get a connection from bb8 redis pool is very high HOT 2
- Unable to use bb8-redis pool connection to execute `query_async` commands on redis HOT 3
- Why bb8-redis can't support redis features? HOT 3
- ACL support for redis HOT 2
- Error sink not called unless debugger is attached with breakpoints HOT 2
- Reentrant deadlock HOT 5
- Reaper default frequency conflicts with other settings
- Unable to connect to secure client using bb8-redis HOT 2
- TimedOut error when has_broken = true HOT 8
- add a tag for v0.8.1 HOT 2
- Expose internal connection type in some way HOT 2
- Support for pool creation without requiring initial connection HOT 2
- Unusually slow to give redis connections HOT 7
- Close pool and all connections? HOT 1
- Support for pool creation with concurrent connections creation HOT 5
- Attempt to subtract with overflow, new version 8.2 HOT 5
- Timeout Issue with bb8-redis 0.14.0 on GCP Memorystore Redis HOT 5
- Changelog HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bb8.