Как я могу вызвать закрепленное будущее из обработчика actix? - PullRequest
0 голосов
/ 11 октября 2019

У меня есть метод асинхронной черты, который возвращает стандартное будущее.

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

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

Обратите внимание, что этот тип это не Unpin .

Я хочу вызвать это из обработчика 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<_>`

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

1 Ответ

0 голосов
/ 14 октября 2019

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

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

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

Вызов .compat() в будущем перед вызовом .into_actor устраняет проблему.

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

...