Workstation technische briefing: waarom Rust blijft een sterke standaard voor veel moderne toepassingen — APIs, Edge, agents en CI/CD-platforms — en hoe u CPU-gebonden correct werken naast een async-runtime. We halen inspiratie (geen letterlijke herdruk) uit het essay van Alice Ryhl Asynchronisatie: wat is blokkering?, met name de Rayon-begeleiding. Companion: blog Bewijsstukken: Polyglot Benchmarks Gerelateerd: polyglot artikel.
- Blokkeren (async sense): voorkomen dat de runtime taken verwisselt — meestal door een lange tijd door te brengen zonder
.await. - CPU-gebonden oplossing: geef de voorkeur aan Rayon (of een speciale thread) boven het vullen van zware berekeningen op Tokio-werknemers.
- IO-gebonden synchronisatiebibliotheken:
tokio::task::spawn_blockingis meestal het juiste zwembad. - Polyglot: Rust is een sterk hulpmiddel onder collega's — meet met Polyglot Benchmarks voordat u een stapel verplicht stelt.
- Bij: conceptuele framing geïnspireerd door Alice Ryhl / ryhl.io; Workstation past het toe op platform engineering.
1. Rust-voordelen die ertoe doen in productievestigingen
Moderne applicatieportfolio's zijn zelden eentalig. Toch belonen bepaalde oppervlakken de eigenschappen van Rust:
- Geheugenveiligheid zonder GC-jitter — eigendom en lenen catch-use-after-free en data races op compilatietijd; latentiegevoelige paden vermijden stop-the-world pauzes.
- Voorspelbare prestaties — kostenloze abstracties en fijne controle over de toewijzing maken Rust concurrerend voor hete API-paden en randtransformaties.
- Onverschrokken samenloop (met structuur) — Verzend/synchroniseer en asynchroniseer ecosystemen (Tokio, async-trait-patronen, kanalen) moedigen ontwerpen aan die schalen onder fan-out.
- Inzetbare binaire bestanden — enkele statische artefacten vereenvoudigen containers voor gateways, agents en CI/CD sidecars.
- Interop in polyglot landgoederen — FFI, Wasm en HTTP houden Rust naast Go-, Python-, JVM- en Lua-randen zonder een herschrijving van alles te forceren.
Workstation's houding komt overeen met onze Polyglot Benchmarks blog en lang artikel: kies de juiste tool voor de begrensde context. Op het live dashboard op polyglot-benchmarks.fictionally.org, Rust (Actix in dat harnas) toont vaak kracht op CPU-gebonden en concurrency-gevoelige HTTP-rijen — nuttig bewijs wanneer een ADR pleit voor Rust op een heet pad, niet op een religie.
2. Coöperatieve planning: de betekenis van "blokkeren"
Async Rust maakt gebruik van coöperatieve planning. De runtime wisselt taken uit wanneer ze een .await. De gedenkwaardige regel van Alice Ryhl geldt overal waar we asynchrone services verzenden:
Async-code mag nooit lang duren zonder een .await.
In deze woordenschat betekent "de draad blokkeren" niet alleen "IO doen". voorkomen dat de runtime de huidige taak verwisselt. Klassieke voetpistolen:
std::thread::sleepin een asynchrone fn (geen wachttijd — timers worden serieel uitgevoerd onderjoin!).- Zware lussen, compressie, crypto, vector wiskunde of JSON-op-steroïden op een Tokio-werker.
- Het houden van een sync mutex over een lange kritieke sectie op de async pool (korte sloten kunnen prima zijn; lange zijn dat niet).
Tijdens een runtime met meerdere threads kun je de bug verbergen totdat je de werkthreads verzadigt. Productieverkeer vindt het voor u. Behandel voor latentie-SLO's tientallen tot honderden microseconden tussen wachttijden als het budget voor coöperatief werk; alles wat langer is, hoort buiten de asynchrone pool.
3. Drie plaatsen om werk te plaatsen dat moet blokkeren
Wanneer u opzettelijk dure CPU moet blokkeren of IO moet synchroniseren, verplaats dat dan van de planningsreeksen van Tokio. Het spiekbriefje (uitgelijnd met de lijst van Ryhl):
| Aanpak | CPU-gebonden | Synchroniseer IO | Loopt voor altijd |
|---|---|---|---|
spawn_blocking | Suboptimaal (groot zwembad) | OK | Nee |
| Rayon | OK | Nee | Nee |
Toegewijd std::thread | OK | OK | OK |
3.1 spawn_blocking voor Sync IO
tokio::task::spawn_blocking schema's op de blokkerende pool van Tokio (standaard honderden threads). Dat past bij bestandssysteemaanroepen en het blokkeren van databasestuurprogramma's. Het is een slechte pasvorm voor aanhoudende CPU omdat overabonnement de OS-planner bestrijdt — prima voor een paar korte berekeningen, riskant als standaard voor parallelle crunching.
3.2 Rayon voor dure CPU
Rayon onderhoudt een pool met de grootte voor CPU-gebonden parallellisme. Het kritieke integratiedetail: do geen blokkeer een Tokio-werker die wacht op Rayon. Spawn op Rayon, stuur het resultaat door tokio::sync::oneshot, en .await de ontvanger aan de asynchrone kant. Parallelle iterators (par_iter) nog steeds die buitenste rayon::spawn omdat ze blokkeren tot ze voltooid zijn.
// Shape only — see ryhl.io for a full walkthrough
async fn parallel_work(data: Vec<i32>) -> i32 {
let (tx, rx) = tokio::sync::oneshot::channel();
rayon::spawn(move || {
let sum: i32 = data.into_iter().sum(); // or par_iter inside
let _ = tx.send(sum);
});
rx.await.expect("rayon task panicked")
}
Credit: dit integratiepatroon is het hart van de Rayon kratsectie op ryhl.io. Workstation beveelt dezelfde vorm aan in productdiensten, dus verzoekthreads blijven planbaar.
3.3 Toegewijde threads voor altijd werken
Een lus die nooit uitkomt (speciale DB-verbindingseigenaar, langlevende brug) mag geen sleuf van beide zwembaden permanent gebruiken. Geef de voorkeur aan std::thread::spawn en communiceren via kanalen.
4. Het advies in kaart brengen op moderne toepassingstypen
| Oppervlak | Blijf asynchroon | lossen |
|---|---|---|
| APIs | Accepteer, authn, fan-out http, streaming | Zware serialisatie, crypto-batches, scoren |
| Edge / gateways | Routing, cache opzoeken, WAF-beslissingen | Zeldzame CPU-transformaties; geef de voorkeur aan Lua/njs wanneer beter gemeten |
| Agenten | Toolorkestratie, MCP-sessies, time-outs | Inbedding prep, eval suites, grote lokale transformaties |
| CI/CD-platforms | Promoot APIs, gezondheidspolls, UI/API | Diepe artefactanalyse, bulkverificatie |
Workstation-producten illustreren de splitsing: Ring Promoter moet promotie- en gezondheidspoorten scherp houden; WSL Proxy houdt randpaden vrij; KubePilot heeft responsieve incidentlussen nodig, zelfs wanneer de analyse zwaar is. Rust (of Go, of Lua) wordt per oppervlak na meting gekozen — nooit omdat een gangdebat tot winnaar uitriep.
5. Architectuurchecklist voor teams die asynchrone Rust gebruiken
- Voorraad wacht op hiaten: profilers en traceringsspanningen die nooit opleveren.
- Classificeer blokkeerwerk: synchroniseer IO versus CPU versus forever-loop.
- Kies het zwembad:
spawn_blocking, Rayon + oneshot of speciale thread. - Load-test met realistische gelijktijdigheid — multi-threaded runtimes verbergen bugs op N=1.
- Documenteer de beslissing in een ADR; voeg Polyglot Benchmarks-rijen toe wanneer taalkeuze in het spel is.
- Lees de Tokio-richtlijnen over gedeelde status en coöperatieve opbrengst voor staartlatentie opnieuw.
Meer hierover
- Alice Ryhl — Asynchronisatie: wat is blokkering? (primaire inspiratie voor de Rayon / spawn_blocking framing).
- Workstation — Polyglot Benchmarks live dashboard.
- Workstation — Polyglot blog · Polyglot-artikel.
- Workstation — begeleidende blog voor een skim versie van deze briefing.
Gepubliceerd door Workstation. Conceptueel krediet voor het openbare schrijven van Alice Ryhl over asynchrone blokkering en Rayon; alle productframing en polyglotbegeleiding zijn Workstation's.