У меня есть tkp-сервер Tokio, который должен передавать отдельные входящие соединения в службу. Как правильно обработать косвенное обращение, чтобы сервер мог работать с различными реализациями служб? Я прибег к звонку tokio::spawn()
внутри службы, потому что не смог найти способ вернуть будущее с косвенным указанием.
Вот минимальный пример того, что я делаю:
extern crate tokio;
use tokio::prelude::future::FutureResult;
use tokio::prelude::*;
struct Subject {
name: String,
}
struct MySvc {
name: String,
}
trait Svc6 {
fn handle6(&self, subject: Subject);
}
impl Svc6 for MySvc {
fn handle6(&self, subject: Subject) {
let task = future::ok((self.name.to_string(), subject))
.and_then(|(n, s)| Ok(println!("#6. Hi {}! My name is {}.", s.name, n)));
tokio::spawn(task);
}
}
#[test]
fn svc6_works() {
let svc = MySvc {
name: "Zorg".into(),
};
let subj = Subject {
name: "Gandalf".into(),
};
tokio::run(future::ok(svc).and_then(|s| Ok(s.handle6(subj))));
}
Хотя это работает с косвенным обращением, меня беспокоит, правильно ли я использую tokio
. Каждый Svc6
импл должен вызывать tokio::spawn()
, а не просто возвращать задачу. Я также предпочел бы, чтобы сервер обрабатывал нерест, поскольку ему, возможно, придется иметь дело с расстановкой приоритетов и очередями. Также сложно протестировать метод, который ничего не возвращает.
Вот ссылка на игровую площадку других вещей, которые я пробовал .
Чтобы увидеть полный контекст, перейдите на Самотопский источник и нажмите «Принять».
Было бы замечательно, если бы реализация метода trait могла возвращать impl Trait!
trait Svc1 {
fn handle1(&self, subject: Subject) -> Future<Item = (), Error = ()>;
}
impl Svc1 for MySvc {
// error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
fn handle1(&self, subject: Subject) -> impl Future<Item = (), Error = ()> {
future::ok(println!(
"#1. Hi {}! My name is {}.",
subject.name, self.name
))
}
}