castomFLOW

Runs waar je op kunt vertrouwen

Niemand merkt een automatisering op tot hij iets twee keer verstuurt

Daarna merkt iedereen het. De vier mechanismen op deze pagina bestaan omdat de fouten van dit soort software altijd dezelfde vier fouten zijn, en ze zijn allemaal weg te nemen door ontwerp in plaats van door zorgvuldigheid.

Simuleren voordat je publiceert

Duw een echte record door een workflow die is uitgeschakeld, en lees precies terug wat er zou zijn gebeurd: het gevolgde pad, elke waarde bij elke stap, de formulering van elk bericht, en het verzoek dat naar elk extern systeem was gegaan.

Er verlaat niets het gebouw. Er wordt geen e-mail verstuurd, geen factuur aangemaakt, geen betaling geprobeerd, geen rij weggeschreven. Externe aanroepen worden vastgelegd als intenties, met de payload die verstuurd zou zijn, zodat je kunt zien of de mapping klopt voordat het iemands probleem wordt.

Simulaties zijn hoe je de vraag beantwoordt die mensen weerhoudt een automatisering aan te zetten: wat doet dit eigenlijk?

Simulatie · order 88 214Niets verzonden
  • 1Adres validerenGevonden. Zou 6 velden wegschrijven.
  • ?VoorwaardeOrder boven 1 000 zł? Nee — 289,00 zł. Korte pad gevolgd.
  • 3FactuurZou een POST sturen naar het factureringssysteem. Payload volledig weergegeven.
  • !Hier onderscheptBtw-tarief gemapt vanuit het verkeerde veld. Gevonden in een simulatie in plaats van in de inbox van een accountant.

Verstuurd: nietsGefactureerd: niets

Een run loopt de versie af waarop hij is binnengekomen

Het publiceren van een wijziging in een workflow raakt de runs die er al in zitten niet. Elke run is vastgepind aan de versie waarop hij is gestart en maakt die versie af, hoe lang het ook duurt en hoeveel je ondertussen ook herschrijft.

Zo kun je een workflow herstructureren terwijl tienduizend mensen er halverwege zitten, en iedereen maakt de flow af die hem was beloofd. Het alternatief — het ontwerp waarbij het hele downstream-pad bij binnenkomst wordt gematerialiseerd — is de reden dat het bewerken van een live automatisering in de meeste tools gevaarlijk voelt. Hier is het niets bijzonders.

Nieuwe runs krijgen de nieuwe versie vanaf het moment dat je publiceert. Welke versie een run gebruikt staat op de run genoteerd, dus een vraag over gedrag in maart heeft in september een antwoord.

Bewerken terwijl het live isv4 → v5
  • 1Voor2 918 runs in uitvoering, allemaal op v4. Sommige in een wachttijd van twee dagen.
  • 2Publiceer v5Twee stappen omgezet, één bericht herschreven.
  • 3NaDie 2 918 maken v4 af. Alles wat vanaf 11:40 start, draait v5.
  • §Niemandkreeg de helft van de ene workflow en de helft van de andere.

Versie vastgelegd op elke runOude versies bewaard

Herhalingen die niet dubbel kunnen versturen

Een stap is een pure functie van zijn invoer, en zijn effecten worden samen met de eigen voortgang van de run naar de volgende stap gecommit. Er is geen venster waarin het bericht al verstuurd is maar de run het nog niet weet.

Dat is de hele truc, en het is een structurele eigenschap in plaats van een belofte. Een worker die midden in een stap wordt gedood — een deploy, een crash, een machine die verdwijnt — laat de run precies waar hij was. Een andere worker pakt hem op en draait de stap opnieuw. Omdat het effect en de voortgang als één geheel committen, zijn ze of allebei gebeurd of allebei niet.

Uitgaande calls naar systemen die idempotency-sleutels ondersteunen krijgen er één mee, afgeleid van de run en de stap, zodat de andere kant de herhaling ook herkent.

Worker gedood midden in het versturenHersteld
  • 1Stap 5 begintStuur de verzendmelding.
  • ✕Worker sterftDeploy. Er was niets gecommit.
  • 2OpgpaktEen andere worker vindt de run nog op stap 5.
  • ✓Eén keer verstuurdDe klant ontving één e-mail, niet twee.

Effecten committen mee met de voortgangIdempotency-sleutel per run en stap

Een log geschreven voor een mens om te lezen

Elke run, elke stap, de genomen tak en de waarde die die bepaalde. Tijden per stap. De request en response van elke externe call, met credentials weggehaald. De versie waarop de run draaide. Waar een run wacht en tot wanneer.

Als iemand vraagt wat er met de bestelling van de veertiende is gebeurd, is er een antwoord, en het vinden ervan kost een minuut in plaats van een middag aan het correleren van de logs van drie systemen.

Runs die falen verzamelen op één plek met de reden gegroepeerd, dus “eenenveertig fouten vannacht” wordt “één leverancier gaf negen minuten lang 503” in plaats van eenenenveertig losse onderzoeken.

Vannacht, gegroepeerd41 fouten
  • 1Eén oorzaakLeveranciers-API gaf 503 tussen 02:41 en 02:50.
  • 2Wat er gebeurdeAlle 41 opnieuw geprobeerd; 39 slaagden bij de tweede poging.
  • 3OvergeblevenTwee zijn gestopt en wachten op een persoon. Allebei staan ze vermeld met de rij die faalde.
  • §Geen eenenveertigonderzoeken. Eén, en een beslissing over twee records.

Credentials weggehaaldVersie vastgelegd

Wat we niet beweren

We publiceren geen uptime-cijfer op een marketingpagina, want een getal zonder meetvenster en zonder definitie van “up” is versiering. Als je er contractueel één nodig hebt, vraag erom en we praten over wat we echt kunnen toezeggen.

We kunnen ook de API van iemand anders niet betrouwbaar maken. Als een provider plat ligt, wacht een workflow die ervan afhangt, probeert opnieuw en stopt uiteindelijk met een duidelijke reden. Wat we wel kunnen beloven, is dat de fout zichtbaar is, dat hij niets corrumpeert, en dat hervatten het bericht geen tweede keer verstuurt.

Over wachttijden: een run die twee dagen wacht is een wake_at op de run, geen job die in een wachtrij staat. Daarom kan een workflow honderdduizend runs drie weken laten wachten zonder dat het iets kost, en waarom het aantal wachtende runs niets is waar je over na hoeft te denken.

De run waar je nooit over nadenkt, is degene die werkte.