Цепочка фьючерсов в Actix с Rusoto - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь отправить сообщение актеру, чтобы вернуть объект, а затем отправить материал на S3, используя rusoto.

Код на данный момент:

use actix_web::{
    actix::{Actor, Addr, Handler, Message, SyncArbiter, SyncContext, System},
    server, App, Error, FutureResponse, HttpRequest, HttpResponse,
};
use futures::{Future, Stream};
use rusoto_core::Region;
use rusoto_s3::{PutObjectRequest, S3Client, S3};

struct AppState {
    pub db: Addr<Db>,
}

struct MyMessage {
    id: i8,
}

struct DatabaseRecord {
    id: i8,
    name: String,
}

impl Message for MyMessage {
    type Result = Result<DatabaseRecord, Error>;
}

struct Db();
impl Actor for Db {
    type Context = SyncContext<Self>;
}

impl Handler<MyMessage> for Db {
    type Result = Result<DatabaseRecord, Error>;
    fn handle(&mut self, m: MyMessage, _: &mut Self::Context) -> Self::Result {
        Ok(DatabaseRecord {
            id: 1,
            name: String::from("Test"),
        })
    }
}

fn main() {
    let sys = System::new("test");
    let db = SyncArbiter::start(1, move || Db());

    server::new(|| App::with_state(AppState { db: db }).resource("/", |r| r.f(test)))
        .bind("localhost:8080")
        .unwrap()
        .start();

    sys.run();
}

fn test(req: &HttpRequest<AppState>) -> FutureResponse<HttpResponse> {
    req.state()
        .db
        .send(MyMessage { id: 1 })
        .from_err()
        .and_then(|r| {
            let client = S3Client::new(Region::Custom {
                name: "test".to_owned(),
                endpoint: String::from("https://localhost:9000"),
            });

            client.put_object(PutObjectRequest {
                bucket: String::from("test"),
                key: String::from("test"),
                ..Default::default()
            })
        })
        .then(|result| Ok(HttpResponse::Ok().body("OK")))
}

Со следующими зависимостями, объявленными в Cargo.toml:

actix-web = "0.7"
rusoto_core = "0.37"
rusoto_s3 = "0.37"
futures = "0.1.25"

Однако вещи не компилируются;компилятор жалуется:

error[E0277]: the trait bound `rusoto_s3::generated::PutObjectError: std::convert::From<actix::address::MailboxError>` is not satisfied
  --> src/main.rs:58:10
   |
58 |         .and_then(|r| {
   |          ^^^^^^^^ the trait `std::convert::From<actix::address::MailboxError>` is not implemented for `rusoto_s3::generated::PutObjectError`
   |
   = help: the following implementations were found:
             <rusoto_s3::generated::PutObjectError as std::convert::From<rusoto_core::request::HttpDispatchError>>
             <rusoto_s3::generated::PutObjectError as std::convert::From<rusoto_core::xmlutil::XmlParseError>>
             <rusoto_s3::generated::PutObjectError as std::convert::From<rusoto_credential::CredentialsError>>
             <rusoto_s3::generated::PutObjectError as std::convert::From<std::io::Error>>
   = note: required because of the requirements on the impl of `futures::future::Future` for `futures::future::from_err::FromErr<actix::address::message::Request<Db, MyMessage>, rusoto_s3::generated::PutObjectError>`

error[E0277]: the trait bound `rusoto_s3::generated::PutObjectError: std::convert::From<actix::address::MailboxError>` is not satisfied
  --> src/main.rs:57:10
   |
57 |         .from_err()
   |          ^^^^^^^^ the trait `std::convert::From<actix::address::MailboxError>` is not implemented for `rusoto_s3::generated::PutObjectError`
   |
   = help: the following implementations were found:
             <rusoto_s3::generated::PutObjectError as std::convert::From<rusoto_core::request::HttpDispatchError>>
             <rusoto_s3::generated::PutObjectError as std::convert::From<rusoto_core::xmlutil::XmlParseError>>
             <rusoto_s3::generated::PutObjectError as std::convert::From<rusoto_credential::CredentialsError>>
             <rusoto_s3::generated::PutObjectError as std::convert::From<std::io::Error>>
...