问题是将可变的Arc引用传递给超级service_fn处理程序

问题描述 投票:1回答:1

我一直在尝试以下方面

显示相关的导入和代码

use std::sync::{Arc, Mutex};
use std::thread;
use hyper::rt::{self, Future, Stream};
use hyper::service::service_fn;
use hyper::{Body, Request, Response, Server, StatusCode};

pub struct ChallengeState;
pub struct ChallengeResponse;

type BoxFut<'a> = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send + 'a>;

fn handle_challengeproof<'a>(
    req: Request<Body>,
    challenge: &Arc<Mutex<ChallengeState>>,
) -> BoxFut<'a> {
    let resp = req.into_body().concat2().map(move |body| {
        let challenge_lock = challenge.lock().unwrap();
        Response::builder()
        .status(StatusCode::OK)
        .body(Body::from("test"))
        .unwrap()
    });
    Box::new(resp)
}

fn handle<'a>(
    req: Request<Body>,
    challenge: &Arc<Mutex<ChallengeState>>,
) -> BoxFut<'a> {
    handle_challengeproof(req, challenge)
}

pub fn run_listener(
    challenge: Arc<Mutex<ChallengeState>>,
) -> thread::JoinHandle<()> {
    let addr = ([127, 0, 0, 1], 9999).into();

    let listener_service = move || {
        let challenge = Arc::clone(&challenge);
        service_fn(move |req: Request<Body>| {
            handle(req, &challenge)
        })
    };

    let server = Server::bind(&addr)
        .serve(listener_service)
        .map_err(|_| () );

    thread::spawn(move || {
        rt::run(server);
    })
}

我一直试图通过传递对handle方法的引用来避免额外的Arc克隆,但似乎无法解决这个问题。避免句柄()的生命周期有关于期望静态生命周期的不同错误。

代码仅使用相关内容更新@ https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10ea31450e88a122455006760d7fcdd1

rust future smart-pointers rust-tokio hyper
1个回答
0
投票

Arc的重点在于它计算有多少引用,这些引用在克隆时发生。传递参考Arc失败了这一点。

而不是传递引用,传递Arc本身。所以handle的签名变成:

fn handle<'a>(
    req: Request<Body>,
    challenge: Arc<Mutex<ChallengeState>>,
) -> BoxFut<'a>

通过闭包引用传递Arc是不可能的,因为你会引用一些立即超出范围的东西。相反,将Arc移动到handle

let listener_service = move || {
    service_fn(move |req: Request<Body>| handle(req, challenge))
}; 
© www.soinside.com 2019 - 2024. All rights reserved.