Stop met het Fiksen van Gedistribueerde Systemen en Begin te Leven met Restate
Stel je dit voor: je schrijft een microservice voor betalingsverwerking. Halverwege het proces flikkert het netwerk, de database time-out, of de container start gewoon opnieuw op. Wat gebeurt er met de transactie? In een klassiek scenario moet je handmatig retry-logica implementeren, idempotentie bijhouden, message queues configureren, en hoogstwaarschijnlijk een complex saga-patroon introduceren. Het is pijnlijk, tijdrovend, en verandert je code in een doolhof van error handlers.
Ik heb onlangs Restate ontdekt, een project dat dit probleem aan de infrastructuur-laag aanpakt. De ontwikkelaars noemen het "Durable Execution" — fouttolerante code-uitvoering. Het idee is dat je code onsterfelijk wordt: als een proces crasht, hervat Restate het precies waar het gebleven was, met behoud van alle variabelen en status.
Wat is dit eigenlijk
Restate is een Rust-binary die werkt als een proxy-server en coördinator voor je services. Het neemt al het vervelende werk van statusbeheer en aanroepen op zich. Je schrijft gewone code in TypeScript, Python of Go, gebruikt de SDK, en plotseling worden je functies betrouwbare workflows.
Het belangrijkste verschil met zware oplossingen zoals Temporal is dat Restate veel gemakkelijker te starten is. Je hebt geen massale setup van databases en complexe workers nodig. Je kunt gewoon een enkele binary of Docker-container draaien en aan de slag gaan.
Hoe Restate in de praktijk helpt
Het project bevat verschillende coole concepten die je leven echt vereenvoudigen.
Gegarandeerde uitvoering
Als je een functie via Restate hebt aangeroepen, wordt deze uitgevoerd tot het einde. Punt. Als de server die je code draait crasht, wacht Restate tot deze terugkomt en gaat verder vanaf de laatste succesvolle stap. Je hoeft je geen zorgen meer te maken of de e-mail twee keer naar de gebruiker is verzonden of dat er twee keer geld is afgeschreven.
Slimme timers en promises
Meestal is het implementeren van een vertraging in een gedistribueerd systeem een hele onderneming. Je moet een bericht in een delay-queue plaatsen of een cron-job instellen. Bij Restate schrijf je gewoon ctx.sleep(duration). De thread blokkeert niet nutteloos: de service kan volledig afsluiten, en drie dagen later "wakkert" Restate hem op en gaat verder met de uitvoering.
Status direct in de code
Restate laat je K/V-status opslaan gebonden aan een specifieke entiteit (bijvoorbeeld een gebruiker-ID). Het lijkt op gewoon object-werk, maar onder de motorkap garandeert Restate dat de data consistent is en altijd beschikbaar is samen met het verzoek. Dit is vooral handig voor serverless architecturen waar functies typisch geen geheugen hebben.
Hoe het er in code uitziet
Stel dat we een gebruikersregistratieproces met e-mailbevestiging moeten implementeren. In TypeScript met de Restate SDK zou het er zo uitzien:
import * as restate from "@restatedev/restate-sdk";
const userService = restate.service({
name: "users",
handlers: {
register: async (ctx: restate.Context, user: { id: string, email: string }) => {
// Сохраняем состояние
ctx.set("status", "pending");
// Отправляем письмо (Restate гарантирует, что это случится 1 раз)
await ctx.run(() => sendWelcomeEmail(user.email));
// Ждем подтверждения или таймаута в 24 часа
const confirmed = await ctx.awakeable<boolean>("email-confirmed");
if (confirmed) {
ctx.set("status", "active");
}
}
}
});
Hier garandeert ctx.run dat het side effect (het verzenden van de e-mail) succesvol wordt uitgevoerd, en het resultaat wordt gecachet. Als de functie crasht na het verzenden, slaat Restate bij herstart deze stap simpelweg over, wetende dat het al gedaan is.
De technische kant
Het project is geschreven in Rust, wat uitstekende prestaties geeft. Architecturally fungeert Restate als een invoker. Het ontvangt inkomende verzoeken via HTTP/gRPC, schrijft ze naar zijn log, en roept je handlers aan.
Interessant is dat Restate de uitvoering kan "suspenden". Als je code wacht op een antwoord van een externe API of een timer, maakt Restate resources vrij. Wanneer de gebeurtenis plaatsvindt, herstelt het de uitvoeringscontext. Dit maakt het mogelijk om duizenden langlopende processen te draaien op bescheiden hardware.
Wie zou het moeten proberen
Restate vult perfect de gaten in projecten waar:
- Er veel aanroepketens tussen microservices zijn.
- Je complexe ketens van acties moet bouwen (saga's, workflows).
- Je AI-agents gebruikt die lang moeten wachten op LLM-antwoorden en conversatiecontext moeten behouden.
- Er vertraagde uitvoeringstaken zijn (herinner aan verlaten winkelwagen over 2 uur).
Het project ontwikkelt zich actief, met bijna 4.000 sterren op GitHub. SDK's zijn beschikbaar voor TypeScript/JavaScript, Java/Kotlin, Python, Go en Rust.
Natuurlijk hoef je niet te haasten om morgen een nieuwe infrastructuurcomponent in de productie van een grote bank te trekken — eerst moet je het lokaal proberen. Maar voor startups of nieuwe features in bestaande projecten kan het weken ontwikkeltijd besparen.
Je kunt het letterlijk in een paar minuten proberen:
brew install restatedev/tap/restate-server
restate-server
En dat is het, je hebt een lokale omgeving voor het draaien van fouttolerante applicaties. Misschien is dit momenteel de laagste instapdrempel naar de wereld van Durable Execution.
Gerelateerde projecten