Как я могу вызвать закрепленное будущее из обработчика actix?

У меня есть метод async trait, который возвращает std Future:

Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<(dyn Error + 'static)>>> + Send>>

ResultType - это связанный тип признака, который равен Sync + Send.

Обратите внимание, что этот тип не открепляется.

Я хочу вызвать это из обработчика actix, а затем что-нибудь сделать с результатом.

Например:

impl StreamHandler<ws::Message, ws::ProtocolError> for MyActor {
    fn handle(&mut self, msg: ws::Message) {
        let fut = get_future();
        let actor_fut = fut
            .into_actor(&self)
            .map(|r, _actor, ctx| {
                ctx.text(r.map(|| ...))
            });

        ctx.spawn(actor_fut);
    }
}

Это не удается, потому что into_actor становится владельцем будущего, что запрещено Pin. Очищенное сообщение об ошибке выглядит так:

error[E0599]: no method named `into_actor` found for type `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>` in the current scope
   --> src/app_socket.rs:194:26
    |
194 |                         .into_actor(&self)
    |                          ^^^^^^^^^^ method not found in `Pin<Box<dyn Future<Output = Result<Vec<ResultType>, Box<dyn Error>>> + Send>>`
    |
    = note: the method `into_actor` exists but the following trait bounds were not satisfied:
            `&dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapFuture<_>`
            `&dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapStream<_>`
            `&mut dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapFuture<_>`
            `&mut dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapStream<_>`
            `&mut Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapFuture<_>`
            `&mut Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapStream<_>`
            `&Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapFuture<_>`
            `&Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapStream<_>`
            `dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapFuture<_>`
            `dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send : WrapStream<_>`
            `Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapFuture<_>`
            `Pin<std::boxed::Box<dyn Future<Output = Result<std::vec::Vec<ResultType>, std::boxed::Box<dyn std::error::Error>>> + Send>> : WrapStream<_>`

Как я могу это сделать?


person Zac Pullar-Strecker    schedule 11.10.2019    source источник
comment
Для чего вам нужно Pin будущее? Я бы понял, что привязать генератор будущего к самому будущему кажется очень эзотерическим.   -  person Sébastien Renauld    schedule 11.10.2019
comment
Это происходит из-за ящика async-trait. См. github.com/dtolnay/async-trait#explanation.   -  person Zac Pullar-Strecker    schedule 11.10.2019


Ответы (1)


Настоящая проблема заключалась не в том, что будущее было привязано, а в том, что оно реализовало неправильную черту будущего.

В этом разделе закрепления объясняется, что poll реализован для Pin<ref T: Future>.

Следовательно, into_actor подпись self: impl Future -> WrapFuture<_> в порядке. Проблема заключалась в том, что метод async возвратил будущую реализацию std::future::Future, а into_actor ожидал futures01::future::Future.

Звонок .compat() в будущем перед звонком .into_actor решает проблему.

См. этот пост подробнее о конвертации фьючерсов.

person Zac Pullar-Strecker    schedule 13.10.2019