如何在actix-web中执行异步函数?

4
以下是一个 asyncconnect() 函数。
use actix_web::client::Client;
use futures::compat::Future01CompatExt;
use futures::future::{FutureExt, TryFutureExt};

pub async fn connect() {
    let request = Client::default().get("https://www.google.com").send();

    // compat() converts a v0.1 futures::future::Future<Item = T, Error = E>
    // into a std::future::Future<Output = Result<T, E>>.
    let result = request.compat().await;

    if let Err(e) = result {
        println!("{:?}", e);
        return;
    }
    if let Ok(response) = result {
        println!("{:?}", response);
        return;
    }
}

首先我尝试使用 futures::executor::ThreadPool::run 执行 connect()。但是由于必须在actix框架上下文中使用actix_web::client::Client,因此会出现错误。

如何在actix上下文中执行connect()?

我也尝试了下面的代码。但它无法编译。

let future03 = async {
    connect().await;
};
let future01 = future03.unit_error().boxed().compat();
actix::Arbiter::spawn(future01);

它以编译错误结束。

error[E0277]: `(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)` cannot be sent between threads safely
  --> src/main.rs:29:42
   |
29 |     let future01 = future03.unit_error().boxed().compat();
   |                                          ^^^^^ `(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>`
   = note: required because it appears within the type `std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>`
   = note: required because it appears within the type `futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>`
   = note: required because it appears within the type `futures::future::either::Either<futures::future::map_err::MapErr<tokio_timer::timeout::Timeout<futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>, [closure@DefId(150:272 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[3])]>, futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>`
   = note: required because it appears within the type `futures::future::either::Either<futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>, futures::future::either::Either<futures::future::map_err::MapErr<tokio_timer::timeout::Timeout<futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>, [closure@DefId(150:272 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[3])]>, futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>>`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `{impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `{impl core::future::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `futures_util::future::unit_error::UnitError<impl core::future::future::Future>`

error[E0277]: `std::rc::Rc<std::cell::RefCell<actix_http::h1::payload::Inner>>` cannot be sent between threads safely
  --> src/main.rs:29:42
   |
29 |     let future01 = future03.unit_error().boxed().compat();
   |                                          ^^^^^ `std::rc::Rc<std::cell::RefCell<actix_http::h1::payload::Inner>>` cannot be sent between threads safely
   |
   = help: within `futures_util::future::unit_error::UnitError<impl core::future::future::Future>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::RefCell<actix_http::h1::payload::Inner>>`
   = note: required because it appears within the type `actix_http::h1::payload::Payload`
   = note: required because it appears within the type `actix_http::payload::Payload<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>`
   = note: required because it appears within the type `awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>`
   = note: required because it appears within the type `std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `std::option::Option<std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>>`
   = note: required because it appears within the type `futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `futures::future::either::Either<futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>, futures::future::either::Either<futures::future::map_err::MapErr<tokio_timer::timeout::Timeout<futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>, [closure@DefId(150:272 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[3])]>, futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>>`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `{impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `{impl core::future::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `futures_util::future::unit_error::UnitError<impl core::future::future::Future>`

error[E0277]: `(dyn actix_http::error::ResponseError + 'static)` cannot be sent between threads safely
  --> src/main.rs:29:42
   |
29 |     let future01 = future03.unit_error().boxed().compat();
   |                                          ^^^^^ `(dyn actix_http::error::ResponseError + 'static)` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `(dyn actix_http::error::ResponseError + 'static)`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn actix_http::error::ResponseError + 'static)>`
   = note: required because it appears within the type `std::boxed::Box<(dyn actix_http::error::ResponseError + 'static)>`
   = note: required because it appears within the type `actix_http::error::Error`
   = note: required because it appears within the type `actix_http::client::error::SendRequestError`
   = note: required because it appears within the type `std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `std::option::Option<std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>>`
   = note: required because it appears within the type `futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `futures::future::either::Either<futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>, futures::future::either::Either<futures::future::map_err::MapErr<tokio_timer::timeout::Timeout<futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>, [closure@DefId(150:272 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[3])]>, futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>>`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `{impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `{impl core::future::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `futures_util::future::unit_error::UnitError<impl core::future::future::Future>`

error[E0277]: `(dyn futures::stream::Stream<Error = actix_http::error::PayloadError, Item = bytes::bytes::Bytes> + 'static)` cannot be sent between threads safely
  --> src/main.rs:29:42
   |
29 |     let future01 = future03.unit_error().boxed().compat();
   |                                          ^^^^^ `(dyn futures::stream::Stream<Error = actix_http::error::PayloadError, Item = bytes::bytes::Bytes> + 'static)` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `(dyn futures::stream::Stream<Error = actix_http::error::PayloadError, Item = bytes::bytes::Bytes> + 'static)`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn futures::stream::Stream<Error = actix_http::error::PayloadError, Item = bytes::bytes::Bytes> + 'static)>`
   = note: required because it appears within the type `std::boxed::Box<(dyn futures::stream::Stream<Error = actix_http::error::PayloadError, Item = bytes::bytes::Bytes> + 'static)>`
   = note: required because it appears within the type `actix_http::payload::Payload`
   = note: required because it appears within the type `actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>`
   = note: required because it appears within the type `actix_http::payload::Payload<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>`
   = note: required because it appears within the type `awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>`
   = note: required because it appears within the type `std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `std::option::Option<std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>>`
   = note: required because it appears within the type `futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `futures::future::either::Either<futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>, futures::future::either::Either<futures::future::map_err::MapErr<tokio_timer::timeout::Timeout<futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>, [closure@DefId(150:272 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[3])]>, futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>>`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `{impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `{impl core::future::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `futures_util::future::unit_error::UnitError<impl core::future::future::Future>`

error[E0277]: `(dyn std::any::Any + 'static)` cannot be sent between threads safely
  --> src/main.rs:29:42
   |
29 |     let future01 = future03.unit_error().boxed().compat();
   |                                          ^^^^^ `(dyn std::any::Any + 'static)` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `(dyn std::any::Any + 'static)`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn std::any::Any + 'static)>`
   = note: required because it appears within the type `std::boxed::Box<(dyn std::any::Any + 'static)>`
   = note: required because it appears within the type `(std::any::TypeId, std::boxed::Box<(dyn std::any::Any + 'static)>)`
   = note: required because of the requirements on the impl of `std::marker::Send` for `hashbrown::raw::RawTable<(std::any::TypeId, std::boxed::Box<(dyn std::any::Any + 'static)>)>`
   = note: required because it appears within the type `hashbrown::map::HashMap<std::any::TypeId, std::boxed::Box<(dyn std::any::Any + 'static)>>`
   = note: required because it appears within the type `actix_http::extensions::Extensions`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::cell::RefCell<actix_http::extensions::Extensions>`
   = note: required because it appears within the type `actix_http::message::ResponseHead`
   = note: required because it appears within the type `awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>`
   = note: required because it appears within the type `std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `std::option::Option<std::result::Result<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>>`
   = note: required because it appears within the type `futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>`
   = note: required because it appears within the type `futures::future::either::Either<futures::future::result_::FutureResult<awc::response::ClientResponse<actix_http::encoding::decoder::Decoder<actix_http::payload::Payload>>, actix_http::client::error::SendRequestError>, futures::future::either::Either<futures::future::map_err::MapErr<tokio_timer::timeout::Timeout<futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>, [closure@DefId(150:272 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[3])]>, futures::future::map::Map<std::boxed::Box<(dyn futures::future::Future<Item = awc::response::ClientResponse, Error = actix_http::client::error::SendRequestError> + 'static)>, [closure@DefId(150:269 ~ awc[6b54]::request[0]::{{impl}}[0]::send_body[0]::{{closure}}[1]) 0:bool]>>>`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `impl futures::future::Future`
   = note: required because it appears within the type `{impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:5:24: 20:2 {impl futures::future::Future, futures_util::compat::compat01as03::Compat01As03<impl futures::future::Future>, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `{impl core::future::future::Future, ()}`
   = note: required because it appears within the type `[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]`
   = note: required because it appears within the type `std::future::GenFuture<[static generator@src/main.rs:26:26: 28:6 {impl core::future::future::Future, ()}]>`
   = note: required because it appears within the type `impl core::future::future::Future`
   = note: required because it appears within the type `futures_util::future::unit_error::UnitError<impl core::future::future::Future>`

error: aborting due to 5 previous errors

我仍在学习Rust,可以有人帮忙吗?感激不尽。

Rust版本:1.39夜版

[dependencies]
actix = "0.8.3"
actix-web = "1.0.5"

# https://rust-lang-nursery.github.io/futures-rs/blog/2019/04/18/compatibility-layer.html
# Rust’s futures ecosystem is currently split in two: 
# On the one hand we have the vibrant ecosystem built around futures@0.1 with its many libraries working on stable Rust 
# and on the other hand there’s std::future ecosystem with support for the ergonomic and powerful async/await language feature. 
# To bridge the gap between these two worlds we have introduced a compatibility layer as part of the futures@0.3 extension to std::future. 
[dependencies.futures-preview]
version = "0.3.0-alpha.18"
default-features = false
features = ["compat", "async-await", "nightly"]
1个回答

0
let future01 = future03.unit_error().boxed_local().compat();

boxed_local() 将 Future 包装在 Box 中,固定它。 类似于 boxed(),但没有发送要求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接