首页 > 解决方案 > 指定 HTTP 请求时间的变量生命周期

问题描述

我正在尝试在 RocksDB 之上实现一个 HTTP 层作为玩具项目。我的想法是创建一个端点,该端点返回一个“永无止境”的数据流,该数据流在客户端关闭连接时完成。

我需要一个变量的生命周期与 HTTP 请求的生命周期一样长:Rust playground

extern crate hyper;
extern crate tokio;

use std::convert::Infallible;
use std::net::SocketAddr;

use bytes::Bytes;
use futures::Stream;
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};

async fn hello_world(_: Request<Body>) -> Result<Response<Body>, Infallible> {
    let add_underscore = "_";
    let iter = vec!["hello", "world"]
        .into_iter()
        .map(|x| format!("{}{}", x, add_underscore))
        .map(|x| Ok(Bytes::from(x)));

    let stream: Box<dyn Stream<Item=Result<Bytes, Box<dyn std::error::Error + Send + Sync>>> + Send + Sync> 
        = Box::new(futures::stream::iter(iter));

    let response = http::Response::builder()
        .header(
            "Content-Type",
            "application/octet-stream",
        )
        .body(Body::from(stream))
        .unwrap();

    Ok(response)
}

#[tokio::main]
async fn main() {
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

    let make_svc = make_service_fn(|_conn| async {
        Ok::<_, Infallible>(service_fn(hello_world))
    });

    let server = Server::bind(&addr).serve(make_svc);

    if let Err(e) = server.await {
        eprintln!("server error: {}", e);
    }
}
error[E0597]: `add_underscore` does not live long enough
  --> src/main.rs:16:37
   |
16 |         .map(|x| format!("{}{}", x, add_underscore))
   |              ---                    ^^^^^^^^^^^^^^ borrowed value does not live long enough
   |              |
   |              value captured here
...
19 |     let stream: Box<dyn Stream<Item=Result<Bytes, Box<dyn std::error::Error + Send + Sync>>> + Send + Sync> = Box::new(futures::stream::iter(iter));
   |                                                                                                               ------------------------------------- cast requires that `add_underscore` is borrowed for `'static`
...
29 | }
   | - `add_underscore` dropped here while still borrowed

如果您在本地运行代码并注释 2 行,add_underscore您将获得一个编译版本:

curl -XGET -v --silent 127.0.0.1:3000
*   Trying 127.0.0.1:3000...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:3000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: application/octet-stream
< transfer-encoding: chunked
< date: Wed, 04 Mar 2020 15:03:39 GMT
<
* Connection #0 to host 127.0.0.1 left intact
helloworld

我想我理解这个问题:它的生命周期add_underscore与函数一样长,hello_world但请求的生命周期更长,因为它是一个未来。我可以做到,'static但在真正的项目中,它是动态的,按需创建(在函数内部或作为参数注入)。

我认为我必须将生命附加add_underscore到未来的生命(我认为),但我不知道如何。

我什至不确定板条箱的哪一部分是需要'static一生的。

标签: rustrust-tokiohyper

解决方案


推荐阅读