0 Tage Serie
rust / expert
Snippet

Gleichzeitiges Ausführen von Futures mit einem benutzerdefinierten Select-Multiplexer

Dieses Snippet zeigt, wie man das Future-Trait manuell implementiert, um einen benutzerdefinierten Select-Kombinator zu erstellen, der zwei Futures gleichzeitig abfragt (polls) und das Ergebnis der ersten zurückgibt, die fertiggestellt wird. Es verwendet generische Einschränkungen und Pin-Projektion, um die zugrunde liegenden Futures sicher und blockierungsfrei abzufragen.

snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
pub struct Select<A, B> {
fut_a: A,
fut_b: B,
}
impl<A, B, T> Future for Select<A, B>
where
A: Future<Output = T> + Unpin,
B: Future<Output = T> + Unpin,
{
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if let Poll::Ready(val) = Pin::new(&mut self.fut_a).poll(cx) {
return Poll::Ready(val);
}
if let Poll::Ready(val) = Pin::new(&mut self.fut_b).poll(cx) {
return Poll::Ready(val);
}
Poll::Pending
}
}
pub fn select<A, B, T>(fut_a: A, fut_b: B) -> Select<A, B>
where
A: Future<Output = T> + Unpin,
B: Future<Output = T> + Unpin,
{
Select { fut_a, fut_b }
}
Erklärung
1
pub struct Select<A, B>
Definiert eine generische Struktur, die zwei verschiedene Future-Typen kapselt, um sie gleichzeitig abzufragen.
2
impl<A, B, T> Future for Select<A, B>
Implementiert das Future-Trait für den Select-Wrapper und stellt sicher, dass beide denselben Ausgabetyp liefern.
3
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>
Die zentrale Methode, die beide Futures unter Verwendung einer gepinnten Referenz überprüft.
4
if let Poll::Ready(val) = Pin::new(&mut self.fut_a).poll(cx)
Fragt die erste Future ab; wenn sie abgeschlossen ist, wird der Wert sofort zurückgegeben.