Naar de inhoud

Blog ·

Het kind wekt de ouder

Een flow die een andere flow aanroept kan bevragen of ingelicht worden. Wij bouwden allebei, en de klok is om een gemeten reden een dag en geen vijf minuten.

Door Provibr

Een flow kan nu een andere flow aanroepen. De aanroepende run stopt, de aangeroepen run start, en als de aangeroepen run klaar is gaat de aanroepende run verder op de ok- of de error-draad.

De hele ontwerpvraag in die zin zit in het woord als. Iets moet opmerken dat het kind klaar is. Er zijn twee manieren om dat te regelen en we zijn met allebei geëindigd, in een bepaalde volgorde, en in de tweede zit een getal waar wat over gediscussieerd is.

De ouder wacht niet, hij wordt ingelicht

De natuurlijke manier om dit te schrijven is een ouder die wacht. De ouder weet op welke run hij wacht, dus hij kan het vragen. Elke tien seconden bevragen, kijken of het kind klaar is, en verdergaan zodra dat zo is.

Dat is de verkeerde kant op, en de reden is dat het kind het al weet. Hij is degene die naar klaar overgaat. De ouder laten vragen betekent dat de informatie van de partij die haar heeft naar de partij die haar nodig heeft reist via een herhaalde vraag, en de frequentie van die vraag is de vertraging van de hele functie.

Het kind meldt zich dus. Zodra een kindrun een eindstand bereikt, zet hij de wektijd op de wachtregel die naar hem wijst op nu, en de gewone wachtrijworker pakt hem bij zijn volgende tik op. Dat is precies hetzelfde mechanisme dat een menselijke goedkeuring gebruikt: een besluit nemen zet de wektijd op nu. Eén kolom stuurt de wachtrij, en er is bewust geen tweede route naar de uitvoerder.

Die melding is één opdracht: werk de wachtregel bij waar de identificatie van de kindrun overeenkomt en de status nog wachtend is.

Waarom die identificatie een kolom is en geen deel van het toestandsblok

De voortzetting van een gepauzeerde wandeling wordt als JSON opgeslagen, en die bevat alles wat de wandeling nodig heeft om te hervatten: de stapel, de bezochte knopen, de variabelen, de tellers. Het zou consistent zijn geweest om de identificatie van het kind daar ook in te zetten.

Het is in plaats daarvan een kolom, en de reden is richting. Al het andere in dat blok wordt door de wandeling gelezen, van binnenuit. Deze ene waarde wordt van buitenaf gelezen, door een kindrun die de rij wil vinden die naar hem wijst. In het blok is dat een scan over elke open wacht in het systeem, en de index die je nodig zou hebben om dat goedkoop te maken is toch deze kolom.

De vreemde sleutel staat op SET NULL en niet op CASCADE. Wordt de kindrun opgeruimd, dan mag de wacht van de ouder niet met hem verdwijnen, want dan hangt er een ouder opgeschort zonder dat er ooit nog iets is dat hem wekt. De verwijzing kwijtraken is te overleven; de rij kwijtraken niet.

De terugvalklok is een dag, en het getal is het argument

De melding is het mechanisme. De klok is het vangnet voor het geval de melding nooit aankomt: een container die halverwege het afronden van het kind omviel, een rij die met de hand aangeraakt is.

De voor de hand liggende waarde voor een vangnet is iets kleins. Vijf minuten voelt verantwoord.

Het is fout, en de reden is wat een kind mag doen. Een kindrun kan een menselijke goedkeuring bevatten, en een goedkeuring kan een deadline hebben die dertig dagen verderop ligt. Met een klok van vijf minuten wordt de ouder van dat kind in die dertig dagen duizenden keren gewekt om erachter te komen dat er niets veranderd is, en elk van die wekkingen is een HTTP-verzoek van de gateway naar de webcontainer.

Vierentwintig uur kost hoogstens dertig zinloze tikken over de langste wacht die het product toestaat, en begrenst de schade van een werkelijk gemiste melding tot één dag. Dat is de afweging, uitgedrukt in de eenheden die ertoe doen: hoeveel verzoeken kost het vangnet als er niets aan de hand is, tegenover hoe lang een echt falen onzichtbaar blijft.

De algemene vorm: een herhalingstussenpoos is niet "zo kort als we ons kunnen veroorloven". Ze is een functie van de langste legitieme wacht, en heb je niet gevraagd hoe lang die is, dan is de tussenpoos een gok.

Een klok die je niet kunt verkorten is een klok die je niet kunt bewijzen

Een vangnet gaat alleen af als het mechanisme eronder faalde. Met de tussenpoos vast op een dag kost aantonen dat het werkt een dag, dus de ronde die het bouwde leverde die tak als onbewezen af, eerlijk gelabeld.

De verleiding is om het met de hand te bewijzen: in de database grijpen, de wektijd naar het verleden verplaatsen, en kijken hoe de run hervat. Dat bewijst het hervatten. Het bewijst de klok niet, want de klok is precies het ding dat je vervangen hebt.

De tussenpoos leest daarom een omgevingsvariabele, en het aangrijpingspunt staat in de bron naast de constante en niet in een testbestand. Het wordt gebruikt door een end-to-end-script dat hem op een paar seconden zet, het vangnet werkelijk laat afgaan, en kijkt hoe een ouder wiens kind nooit iets gemeld heeft zichzelf herstelt.

Twee eigenschappen maken dat aangrijpingspunt veilig om uit te leveren. Het kan de tussenpoos alleen korter maken: de waarde wordt geklemd tegen de productieconstante, dus een verkeerd ingestelde omgeving kan een ouder nooit langer dan een dag laten wachten. En alles wat geen positief getal is valt terug op de productiewaarde.

Die tweede is geen defensief programmeren om het defensief programmeren. Ons voorbeeldbestand met omgevingswaarden kopiëren geeft je de variabele aanwezig en leeg, en een lege string is niet ongedefinieerd. Hem naar een getal omzetten geeft nul. Zonder die zeef zou een gekopieerd configuratiebestand de tussenpoos op nul zetten en elke ouder met een openstaand kind in een wekkerlus tegen de webcontainer duwen. Het verschil tussen een lege string en ongedefinieerd heeft ons eerder geraakt, op een plek waar het een downloadroute een 404 kostte.

Twee grenzen, elk twee keer afgedwongen

Een flow die een flow aanroept roept de vraag op van een flow die zichzelf aanroept. Er zijn twee grenzen, recursie en diepte, en elk ervan wordt op twee plekken afgedwongen.

Statisch, als een flow opgeslagen wordt: de graaf wordt afgelopen, de flows die hij aanroept worden opgezocht, en een cykel of een keten die te diep is wordt geweigerd met de keten benoemd in de fout. Dynamisch, tijdens een run: dezelfde twee grenzen opnieuw, met hun eigen weigeringscodes.

Allebei zijn ze nodig omdat flows onafhankelijk bewerkt worden. Twee flows die los prima zijn kunnen een cykel worden op het moment dat iemand een aanroep aan de tweede toevoegt, en niets valideert de eerste opnieuw. De statische controle is wat een bruikbare foutmelding geeft op het moment dat iemand het nog kan repareren; de dynamische controle is wat werkelijk standhoudt.

De diepte is een kolom op de run en niet iets dat berekend wordt door de ouders af te lopen. Dat gaat in tegen de lijn die we normaal aanhouden, namelijk dat alles wat af te leiden is ook afgeleid hoort te worden. Die lijn houdt hier geen stand, want de verwijzing naar de ouder staat op SET NULL: zodra een ouderrun opgeruimd is, kan de keten niet meer teruggelopen worden en zou de diepte van een draaiend kind onkenbaar worden op precies het moment dat het ertoe doet.

Wat de vervolgronde mat

De takken die dit ontwerp openliet zijn in een latere ronde genomen, en twee daarvan zijn de interessante.

Een kindrun die volledig verdwijnt: de wacht behoudt zijn rij en raakt zijn verwijzing kwijt, de terugvalklok wekt de ouder, en het hervatten vindt geen kind en laat die knoop falen met een specifieke reden in plaats van te blijven hangen. Een graaf die helemaal niet te lezen is levert een andere reden op, dus de twee situaties zijn in het runlogboek te onderscheiden.

Een subflow binnen een lus, in de twee vormen die zich verschillend gedragen: een kind dat binnen het oorspronkelijke verzoek klaar is, en een kind dat zichzelf opschort. Het eerste raakt de wachtrij helemaal niet. Het tweede is de hele functie.

Wat we zouden opschrijven

  1. De partij die het weet hoort het te vertellen en niet gevraagd te worden. Bevragen maakt van je vertraging een instelwaarde.
  2. Hergebruik het wekpad dat je al hebt. Een besluit en een klaar kind zijn voor de wachtrij dezelfde gebeurtenis.
  3. Een waarde die van buiten het toestandsblok gelezen wordt hoort in een kolom. Richting beslist dit, geen consistentie.
  4. SET NULL en niet CASCADE, als de rij die verwijderd zou worden iemands enige manier is om gewekt te worden.
  5. De tussenpoos van een vangnet is een functie van de langste legitieme wacht, en niet van hoe alert je zou willen overkomen.
  6. Formuleer de afweging in verzoeken en uren. Dertig verspilde tikken tegen een dag onzichtbaarheid is een beslissing; "vijf minuten" is een reflex.
  7. Een constante die je niet kunt variëren is een tak die je niet kunt bewijzen. Het aangrijpingspunt hoort naast de constante.
  8. Laat het aangrijpingspunt de zaak alleen veiliger maken, en klem het tegen de productiewaarde.
  9. Een lege omgevingsvariabele is niet ongedefinieerd, en hem naar een getal omzetten geeft je nul.
  10. Controleer een grens waar hij te repareren is en waar hij moet standhouden. Onafhankelijk bewerkte grafen hebben ze allebei nodig.

Voor de duidelijkheid over wat dit is: de mergeverificatie draaide 16 van de 16 stappen zonder een faalregel, de websuite was 4583 groen, packages, gateway en tools samen 7286 groen, de wandeling 75 groen, de statische subflowcontrole 13 groen, de end-to-end-run tegen de ontwikkeldatabase 58 groen, de ontvangersmeting 4 groen, een browsertest met een echte gatewayworker 31 groen waarin een pauze van negentig seconden na vijfennegentig seconden hervatte, de editortest 9 groen en de toegankelijkheidsveeg vond niets op zes pagina's. Toen nog onbewezen: de terugvalklok, een subflow binnen een lus, een verdwenen kindrun, en de tak voor uitgeputte pogingen. Die vier zijn in de volgende ronde genomen.

Uit het platformwerk aan Provibr. Hoe de wandeling iets werd dat naar een rij geschreven kan worden staat in elke zelfaanroep stond in staartpositie, en de ronde die eindelijk de takken bereikte die deze openliet staat in groen omdat hij er niet kon komen.

Begin met één host en één agent

Maak een account aan, installeer de agent met één commando en koppel je eerste Proxmox-host. De proefperiode loopt 14 dagen en vraagt geen betaalgegevens.