In the tokio tests I see they use oneshot::channel
together with serve_with_shutdown
but the the compiler tells me to add use futures_util::future::future::FutureExt
but as you can see in the example below I already added that trait to the scope.
What am I missing?
Here a reprex
run cargo new tokio-test
Cargo.toml
[package]
name = "tokio-test"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tonic = "0.7"
prost = "0.10.1"
tokio = { version = "1.18", features = ["macros", "rt-multi-thread"] }
[build-dependencies]
tonic-build = "0.7.2"
src/main.rs
pub mod console {
tonic::include_proto!("console");
}
use console::console_server::{Console, ConsoleServer};
use console::{ConsoleResponse, InfoRequest};
use tokio::runtime::Runtime;
use tokio::sync::oneshot;
use tonic::{transport::Server, Request, Response};
use futures_util::FutureExt;
#[derive(Default)]
pub struct ConsoleImpl {}
#[tonic::async_trait]
impl Console for ConsoleImpl {
async fn info(
&self,
request: Request<InfoRequest>,
) -> Result<Response<ConsoleResponse>, tonic::Status> {
println!("{}", request.get_ref().text);
Ok(Response::new(ConsoleResponse {}))
}
}
fn main() {
let addr = "[::1]:50051".parse().unwrap();
let maxconsole = ConsoleImpl::default();
println!("Console server listening on {}", addr);
let mut rt = Runtime::new().expect("failed to obtain a new RunTime object");
let (shutdown_send, shutdown_recv) = oneshot::channel::<()>();
let server_future = Server::builder()
.add_service(ConsoleServer::new(maxconsole))
// .serve(addr)
.serve_with_incoming_shutdown(
addr,
shutdown_recv.map(drop),
);
rt.block_on(server_future).expect("failed to successfully run the future on RunTime");
}
src/console.proto
syntax = "proto3";
package console;
service Console {
rpc info (InfoRequest) returns (ConsoleResponse) {}
}
message InfoRequest {
string text = 1;
}
message ConsoleResponse {
}
If you build the project it will complain
❯ cargo build
Updating crates.io index
Compiling tokio-test v0.1.0 (C:\s\tokio-test)
error[E0432]: unresolved import `futures_util`
--> src\main.rs:10:5
|
10 | use futures_util::FutureExt;
| ^^^^^^^^^^^^ use of undeclared crate or module `futures_util`
error[E0599]: `tokio::sync::oneshot::Receiver<()>` is not an iterator
--> src\main.rs:40:27
|
40 | shutdown_recv.map(drop),
| ^^^ `tokio::sync::oneshot::Receiver<()>` is not an iterator
|
::: C:\Users\FrancescElies\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.20.1\src\sync\oneshot.rs:318:1
|
318 | pub struct Receiver<T> {
| ---------------------- doesn't satisfy `tokio::sync::oneshot::Receiver<()>: Iterator`
|
= note: the following trait bounds were not satisfied:
`tokio::sync::oneshot::Receiver<()>: Iterator`
which is required by `&mut tokio::sync::oneshot::Receiver<()>: Iterator`
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
1 | use futures_util::future::future::FutureExt;
|
Some errors have detailed explanations: E0432, E0599.
For more information about an error, try `rustc --explain E0432`.
error: could not compile `tokio-test` due to 2 previous errors
Yes, you added the FutureExt
import, but did not tell Rust where to find that crate. The critical part of the error message is:
error[E0432]: unresolved import `futures_util`
--> src\main.rs:10:5
|
10 | use futures_util::FutureExt;
| ^^^^^^^^^^^^ use of undeclared crate or module `futures_util`
This can be fixed by adding the futures_util
crate to your Cargo.toml
dependency section.