发出将可变Arc引用传递给hyper service_fn处理程序的问题 [英] Issue passing mutable Arc reference to hyper service_fn handler

查看:85
本文介绍了发出将可变Arc引用传递给hyper service_fn处理程序的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试以下

相关的导入和显示的代码

Relevant imports and code shown

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克隆,但似乎无法解决这个问题.避免handle()上存在生命期,有关期货要求静态生命期的错误却有所不同.

I've been trying to avoid an extra clone of Arc by passing a reference to the handle method but can't seem to get around this. Avoiding the lifetime on handle() got a different error regarding futures asking for static lifetime.

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

Code updated with only relevant stuff @ https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=10ea31450e88a122455006760d7fcdd1

推荐答案

Arc 的全部要点是,它计算有多少引用,而这些引用是在克隆时发生的.传递对 Arc 的引用会破坏这一点.

The whole point of an Arc is that it counts how many references there are, which happens when it is cloned. Passing around references to an Arc defeats the point.

传递 Arc 本身,而不是传递引用.因此, handle 的签名变为:

Instead of passing references, pass the Arc itself. So handle's signature becomes:

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

无法通过闭包中的引用传递 Arc ,因为您将引用的内容会立即超出范围.而是将 Arc 移动到 handle :

Passing the Arc by references from the closure isn't possible because you would be referencing something that immediately goes out of scope. Instead, move the Arc into handle:

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

这篇关于发出将可变Arc引用传递给hyper service_fn处理程序的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆