我正在尝试编写一个简单的Rust程序,该程序使用P0934读取Docker统计信息,并使用shiplift将其作为Prometheus指标公开。
shiplift
统计信息示例本身可以正常运行,我正尝试将其集成到服务器中
fn handle(_req: Request<Body>) -> Response<Body> {
let docker = Docker::new();
let containers = docker.containers();
let id = "my-id";
let stats = containers
.get(&id)
.stats().take(1).wait();
for s in stats {
println!("{:?}", s);
}
// ...
}
// in main
let make_service = || {
service_fn_ok(handle)
};
let server = Server::bind(&addr)
.serve(make_service);
但似乎流永远挂起(我无法产生任何错误消息)。
我还在rust-prometheus中尝试了相同的重构(使用take
和wait
而不是tokio::run
),但是在这种情况下,我得到了错误{{ 1}}。 executor failed to spawn task: tokio::spawn failed (is a tokio runtime running this future?)
是否需要tokio
?
编辑:
如果我已正确理解,我的尝试将不起作用,因为shiplift
将阻止wait
执行程序,而tokio
将永远不会产生结果。
答案 0 :(得分:0)
conda install -c conda-forge opencv
的API是异步的,这意味着shiplift
和其他函数将返回wait()
,而不是阻塞主线程直到结果准备就绪。 Future
实际上不会执行任何I / O,直到将其传递给执行者。如您所链接的示例一样,您需要将Future
传递给Future
。您应该阅读tokio docs,以更好地了解如何在rust中编写异步代码。
答案 1 :(得分:0)
在我对hyper
的工作方式的理解中有很多错误。基本上:
service_fn_ok
来创建它(这是用于同步服务):请使用service_fn
; wait
:所有期货都使用相同的执行器,执行将永远挂起(文档中有警告,但很好...); hyper::rt::spawn
可用于异步读取统计信息,而不是在服务中完成船舶运输需要东京吗?
是的。它使用hyper
,如果默认的executor failed to spawn task
执行程序不可用(使用期货几乎总是需要执行程序),则会抛出tokio
。
这是我最终的最低版本(tokio 0.1.20和hyper 0.12):
use std::net::SocketAddr;
use std::time::{Duration, Instant};
use tokio::prelude::*;
use tokio::timer::Interval;
use hyper::{
Body, Response, service::service_fn_ok,
Server, rt::{spawn, run}
};
fn init_background_task(swarm_name: String) -> impl Future<Item = (), Error = ()> {
Interval::new(Instant::now(), Duration::from_secs(1))
.map_err(|e| panic!(e))
.for_each(move |_instant| {
futures::future::ok(()) // unimplemented: call shiplift here
})
}
fn init_server(address: SocketAddr) -> impl Future<Item = (), Error = ()> {
let service = move || {
service_fn_ok(|_request| Response::new(Body::from("unimplemented")))
};
Server::bind(&address)
.serve(service)
.map_err(|e| panic!("Server error: {}", e))
}
fn main() {
let background_task = init_background_task("swarm_name".to_string());
let server = init_server(([127, 0, 0, 1], 9898).into());
run(hyper::rt::lazy(move || {
spawn(background_task);
spawn(server);
Ok(())
}));
}