Asynchroniteit in Rust wordt geïmplementeerd via Future — een object dat een taak vertegenwoordigt waarvan de uitkomst in de toekomst zal worden verkregen. Functies die zijn gedeclareerd met async fn retourneren een anonieme generatorstructuur die de Future-trait implementeert. Voor de uitvoering van asynchrone code wordt een runtime gebruikt (bijvoorbeeld Tokio of async-std), aangezien de standaardbibliotheek geen ingebouwde event loop heeft.
Belangrijkste kenmerken van Rust:
Voorbeeld:
use tokio::time::sleep; use std::time::Duration; async fn foo() { println!("Hallo"); sleep(Duration::from_secs(1)).await; println!("Wereld!"); } #[tokio::main] async fn main() { foo().await; }
Kan een asynchrone functie in Rust standaard onmiddellijk worden uitgevoerd bij aanroep? Waarom?
Antwoord:
Nee. De aanroep van async fn retourneert niet het resultaat, maar een object van het type Future (state machine). Voor daadwerkelijke uitvoering is het nodig om .await aan te roepen of de Future aan de runtime door te geven. De aanroep creëert alleen een beschrijving van de taak, maar voert deze niet uit.
Voorbeeld:
async fn answer() -> u32 { 42 } let fut = answer(); // hier is er geen uitvoering, alleen de creatie van future let result = fut.await; // de uitvoering begint hier
Verhaal
.await aan. Hierdoor werden de belangrijkste threads synchronisch uitgevoerd, wat leidde tot méér dan drie keer zo hoge responstijden en een prestatieverlies.Verhaal
Verhaal
Een van de teamleden vergat de Send/Sync-beperkingen op de types die binnen Future werden gebruikt. Bij het proberen om een future tussen threads te delen, crashte de applicatie met een compilatiefout die om de implementatie van Send voor een bepaalde structuur vroeg, wat leidde tot een herziening van de architectuur voor statusopslag.