如何在MPSC接收器中使用Hyper客户端?

时间:2018-03-04 23:00:00

标签: rust hyper

我有一个应用程序可以在回调中将项目从队列中拉出来。回调是在一个单独的线程中,所以我不能在回调中直接执行任何操作。队列中的项目包括URL和要发布到URL的消息正文。根据响应,我要么从队列中删除该项目,要么重新入队。

这就是我所拥有的:

let (mut sender, receiver) = mpsc::channel(1000);
let mut core = Core::new().expect("Error creating core");
let client = Client::new(&core.handle());

// Consumer callback closure
let consumer = move |_: &mut Channel, deliver: basic::Deliver, headers: basic::BasicProperties, data: Vec<u8>|
{
     let body = match String::from_utf8(data) {
        Ok(body) => body,
        Err(error) => {
            error!("Error parsing message body as UTF8: {}", error);
            return;
        }
    };
    if let Err(error) = sender.try_send(QueueData {
        deliver: deliver,
        headers: headers,
        data: body,
    }) {
        error!("Error sending queue data over channel: {}", error);
    }
};

let work = receiver.for_each(|queue_data| {
    let message = match Message::parse(&queue_data.data, &queue_data.headers) {
        Ok(message) => message,
        Err(error) => return err(Box::new(error) as Box<Error>),
    };

    let uri = match Uri::from_str(&message.body.destination) {
        Ok(uri) => uri,
        Err(error) => return err(Box::new(error) as Box<Error>),
    };

    let mut request: Request = Request::new(Method::Post, uri);
    request.headers_mut().set(ContentType::json());
    request.headers_mut().set(ContentLength(queue_data.data.len() as u64));
    request.set_body(queue_data.data.clone().into_bytes());

    client.request(request)
});

这给了我以下错误:

error[E0271]: type mismatch resolving `<futures::FutureResult<(), std::boxed::Box<std::error::Error>> as futures::IntoFuture>::Error == ()`
   --> src/main.rs:116:29
    |
116 |         let work = receiver.for_each(|queue_data| {
    |                             ^^^^^^^^ expected struct `std::boxed::Box`, found ()
    |
    = note: expected type `std::boxed::Box<std::error::Error>`
               found type `()`

error[E0308]: mismatched types
   --> src/main.rs:132:13
    |
132 |             client.request(request)
    |             ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `futures::FutureResult`, found struct `hyper::client::FutureResponse`
    |
    = note: expected type `futures::FutureResult<(), std::boxed::Box<std::error::Error>>`
               found type `hyper::client::FutureResponse`

这是有道理的,但我找不到任何方式将FutureResponse转换为FutureResult。我在这里错过了什么吗?我可以在未来使用Hyper客户端吗?

1 个答案:

答案 0 :(得分:1)

经过多次挖掘后找到了答案。

首先,我需要使用map而不是for_each,因为for_each期望不返回任何内容。其次,我需要将返回值包装在futures::future::ok中,所以我的更新代码如下所示:

let work = receiver.map(|queue_data| {
    let message = match Message::parse(&queue_data.data, &queue_data.headers) {
        Ok(message) => message,
        Err(error) => return err(Box::new(error) as Box<Error>),
    };

    let uri = match Uri::from_str(&message.body.destination) {
        Ok(uri) => uri,
        Err(error) => return err(Box::new(error) as Box<Error>),
    };

    let mut request: Request = Request::new(Method::Post, uri);
    request.headers_mut().set(ContentType::json());
    request.headers_mut().set(ContentLength(queue_data.data.len() as u64));
    request.set_body(queue_data.data.clone().into_bytes());

    ok(client.request(request))
});

但我必须说,错误信息不是最清楚的......