Runtime

С версией hyper v1.0, которая удалила tokio как зависимость среды выполнения, был введен новый трейт среды выполнения hyper::rt. Если вы все еще хотите использовать tokio, реализация tokio для hyper::rt предоставляется крейтом hyper-util.

Создание собственных реализаций hyper::rt с помощью Tokio

Давайте создадим простые реализации hyper::rt с помощью tokio. Сначала убедитесь, что у вас есть tokio как зависимость в вашем Cargo.toml:

[dependencies]
tokio = { version = "1", features = ["full"] }

Теперь давайте попробуем написать простой исполнитель hyper::rt::Executor, мы назовем его TokioExecutor:

#![allow(unused)]
fn main() {
extern crate hyper;
/// Исполнитель future, который использует потоки `tokio`.
#[non_exhaustive]
#[derive(Default, Debug, Clone)]
pub struct TokioExecutor {}
}

Трейт hyper::rt::Executor ожидает метод execute, который просит среду выполнения выполнить future. tokio позволяет это легко сделать с помощью tokio::spawn:

#![allow(unused)]
fn main() {
extern crate hyper;
extern crate tokio;

use std::future::Future;

use hyper::rt::Executor;

#[non_exhaustive]
#[derive(Default, Debug, Clone)]
pub struct TokioExecutor {}

impl<Fut> Executor<Fut> for TokioExecutor
where
    Fut: Future + Send + 'static,
    Fut::Output: Send + 'static,
{
    fn execute(&self, fut: Fut) {
        tokio::spawn(fut);
    }
}
}

Теперь у нас есть рабочий hyper::rt::Executor с Tokio, и он готов к использованию везде, где требуется Executor. Например, с автоматическим соединением из hyper-util:

#![allow(unused)]
fn main() {
extern crate hyper;
extern crate hyper_util;
extern crate tokio;

use std::future::Future;

use hyper_util::server::conn::auto;
use hyper::rt::Executor;

#[non_exhaustive]
#[derive(Default, Debug, Clone)]
pub struct TokioExecutor {}

impl<Fut> Executor<Fut> for TokioExecutor
where
    Fut: Future + Send + 'static,
    Fut::Output: Send + 'static,
{
    fn execute(&self, fut: Fut) {
        tokio::spawn(fut);
    }
}

impl TokioExecutor {
    pub fn new() -> Self {
        Self {}
    }
}

auto::Builder::new(TokioExecutor::new());
}

Использование реализаций hyper::rt с tokio в hyper-util

Крейт hyper-util предоставляет реализации трейтов hyper::rt с Tokio. Для использования нам понадобится иметь hyper-util как зависимость.

[dependencies]
hyper-util = { version = "0.1", features = ["full"] }

Затем вам просто нужно импортировать и использовать это, как в примере выше:

#![allow(unused)]
fn main() {
extern crate hyper;
extern crate hyper_util;

use hyper::rt::Executor;
use hyper_util::rt::TokioExecutor;
use hyper_util::server::conn::auto;

auto::Builder::new(TokioExecutor::new());
}

В крейте hyper_util есть больше реализаций. Ознакомьтесь с документацией по hyper_util::rt для получения более подробной информации.