跨异步闭包共享数据结构
Sharing data structures across async closures
我一直在尝试跨异步助手共享(只读)数据结构。我想要完成的是创建一个超级服务器,我在其中预先生成一些可供所有请求处理程序使用的数据。
这是 Hyper 入门指南中的示例,扩展了我正在尝试做的事情:
#[tokio::main]
async fn main() {
let address = SocketAddr::from(([127, 0, 0, 1], 3000));
let pages = generate_static_pages();
let make_service = make_service_fn(|_conn| async move {
Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
serve(pages, req)
}))
});
let server = Server::bind(&address).serve(make_service);
if let Err(error) = server.await {
eprintln!("server error: {}", error);
}
}
在我的例子中,generate_static_pages()
returns 具有预生成页面的 HashMap<&'static str, Bytes>
。不幸的是,这个哈希映射不能在编译时生成,因为那样会使事情变得容易得多。现在,我很挣扎,因为 pages
不能被闭包借用:"cannot move out of pages
, a captured variable in an FnMut
closure"
我试图传递一个引用,但这没有用,因为 Rust 无法推断变量的寿命足以让闭包使用。然后我尝试使用 .clone()
但这不起作用,因为它会在变量移动后调用它,但它不能。最后,我尝试用 Arc
包装,但这并没有解决问题,基本上是因为同样的原因。
你会建议我做什么?谢谢!
如果您只需要对页面的不可变引用,那么您应该能够使用 lazy_static
crate。 lazy_static
允许您在运行时初始化静态变量 - 这非常有用!
您的代码最终会类似于:
use lazy_static::lazy_static;
lazy_static! {
static ref PAGES: HashMap<&'static str, Bytes> = generate_static_pages();
}
#[tokio::main]
async fn main() {
let address = SocketAddr::from(([127, 0, 0, 1], 3000));
let make_service = make_service_fn(|_conn| async move {
Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
serve(&PAGES, req)
}))
});
let server = Server::bind(&address).serve(make_service);
if let Err(error) = server.await {
eprintln!("server error: {}", error);
}
}
此外,还有一个 lazy_static
example。
我一直在尝试跨异步助手共享(只读)数据结构。我想要完成的是创建一个超级服务器,我在其中预先生成一些可供所有请求处理程序使用的数据。
这是 Hyper 入门指南中的示例,扩展了我正在尝试做的事情:
#[tokio::main]
async fn main() {
let address = SocketAddr::from(([127, 0, 0, 1], 3000));
let pages = generate_static_pages();
let make_service = make_service_fn(|_conn| async move {
Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
serve(pages, req)
}))
});
let server = Server::bind(&address).serve(make_service);
if let Err(error) = server.await {
eprintln!("server error: {}", error);
}
}
在我的例子中,generate_static_pages()
returns 具有预生成页面的 HashMap<&'static str, Bytes>
。不幸的是,这个哈希映射不能在编译时生成,因为那样会使事情变得容易得多。现在,我很挣扎,因为 pages
不能被闭包借用:"cannot move out of pages
, a captured variable in an FnMut
closure"
我试图传递一个引用,但这没有用,因为 Rust 无法推断变量的寿命足以让闭包使用。然后我尝试使用 .clone()
但这不起作用,因为它会在变量移动后调用它,但它不能。最后,我尝试用 Arc
包装,但这并没有解决问题,基本上是因为同样的原因。
你会建议我做什么?谢谢!
如果您只需要对页面的不可变引用,那么您应该能够使用 lazy_static
crate。 lazy_static
允许您在运行时初始化静态变量 - 这非常有用!
您的代码最终会类似于:
use lazy_static::lazy_static;
lazy_static! {
static ref PAGES: HashMap<&'static str, Bytes> = generate_static_pages();
}
#[tokio::main]
async fn main() {
let address = SocketAddr::from(([127, 0, 0, 1], 3000));
let make_service = make_service_fn(|_conn| async move {
Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
serve(&PAGES, req)
}))
});
let server = Server::bind(&address).serve(make_service);
if let Err(error) = server.await {
eprintln!("server error: {}", error);
}
}
此外,还有一个 lazy_static
example。