Overstappen naar grotere werkruimtes zonder dat iemand hoeft te wachten
Elk Mythex-project krijgt een eigen werkruimte: een kleine cloudcomputer waarop de agent code schrijft en de preview van je app draait. We hadden nieuwe werkruimtes opgehoogd van 1 GB geheugen naar 2 GB, maar oudere bleven op 1 GB — op de dag dat we controleerden, ongeveer een kwart ervan. Onze eerste fix verplaatste een project naar een grotere werkruimte zodra het de volgende keer werd geopend. Op de eerste dag in productie liet dat één persoon zeven minuten wachten. We zetten er een harde tijdslimiet op, en haalden de verplaatsing daarna helemaal uit het openen van een project.
Waarom oude werkruimtes klein bleven
Onze sandboxprovider bepaalt de grootte van een werkruimte wanneer ze wordt aangemaakt, en houdt die vast bij elke pauze en elke hervatting. Het veranderen van het sjabloon — het recept waarmee nieuwe werkruimtes worden gebouwd — geldt alleen voor werkruimtes die na de wijziging zijn aangemaakt. Niets past de bestaande aan.
Dat was belangrijk. Een van de kleine werkruimtes liep tijdens een git push vast op geheugen terwijl de preview opstartte, en reageerde elf minuten niet meer. Een publicatie mislukte daardoor.
Eerste poging: het project verplaatsen wanneer het wakker wordt
Werkruimtes pauzeren wanneer niemand ze gebruikt en worden wakker wanneer het project wordt geopend. Wakker worden leek het juiste moment om een project te verplaatsen, omdat er dan nog niemand in werkt.
De verplaatsing werkte zo:
- Controleer de grootte. Als de werkruimte kleiner is dan 2 GB, verplaats hem. Als de grootte onbekend is, doe niets.
- Stoor geen publicatie. Een publicatie leest de bestanden van de werkruimte, dus als er een loopt, sla de verplaatsing over.
- Pak het project in. Archiveer alles in het project — inclusief de git-geschiedenis, dat wil zeggen elk checkpoint dat het project heeft, en het
.env-bestand van de app, dat van de eigenaar is — maar laat geïnstalleerde afhankelijkheden (node_modules) weg, want die kunnen opnieuw worden geïnstalleerd. - Kopieer het rechtstreeks over. Stream het archief van de oude werkruimte naar een nieuwe van 2 GB, zodat het nooit in het geheugen van onze eigen server hoeft te passen.
- Vergelijk voordat je wisselt. Tel de bestanden, lees het laatste checkpoint, en tel de checkpoints, in beide werkruimtes. Wissel alleen als alle drie overeenkomen.
- Houd de oude bij elke fout. Elke fout of elke afwijking gooit de nieuwe werkruimte weg en opent het project in de oude, zoals voorheen.
Eén detail in de vergelijking was belangrijker dan het lijkt. De controle draait als de beheerdersaccount, en git weigert een repository te lezen die van een andere gebruiker is. Op beide kanten printte het niets — en "niets" kwam overeen met "niets", dus de controle slaagde zonder enige geschiedenis te vergelijken. We hebben git verteld de map te vertrouwen, en een test toegevoegd zodat dat niet terugkomt.
Wat er op de eerste dag misging
Op de eerste dag in productie liep het inpakken van één project tegen een time-out van vijf minuten voor een commando — binnen het wakker worden. De eigenaar wachtte zeven minuten tot zijn werkruimte opende. En omdat de verplaatsing was mislukt, was het project nog klein, dus bij de volgende keer openen zou het opnieuw proberen en de eigenaar opnieuw laten wachten.
Een migratie die iemand laat wachten terwijl hij zijn eigen project opent, is een slechte ruil. Het hele punt van het doen bij het wakker worden was dat niemand het zou merken.
Tweede poging: een harde tijdsbegroting
Dezelfde dag veranderden we vier dingen:
- Eén minuut voor de hele verplaatsing. Elke stap — de grootte controleren, inpakken, de nieuwe werkruimte aanmaken, kopiëren, uitpakken, vergelijken — deelt één budget van 60 seconden. Als dat op is, opent het project in de oude werkruimte.
- Stop het werk, niet alleen het wachten. Opgeven aan onze kant is niet genoeg als het archiveren nog loopt in de werkruimte die de eigenaar op het punt staat te gebruiken. Elk archiefcommando wordt nu binnen de werkruimte zelf gestopt kort voordat het budget afloopt. Als de nieuwe werkruimte arriveert nadat we hebben opgegeven, wordt hij weggegooid.
- Laat de eigenaar niet wachten op opruimen. Het verwijderen van het tijdelijke archief gebeurt nu op de achtergrond.
- Probeer het niet bij elke keer openen opnieuw. Een project dat niet kon worden verplaatst, wordt 24 uur met rust gelaten, zodat een mislukking hooguit één vertraging per dag kost, niet één per keer openen.
Derde poging: haal het uit het wakker worden
Dat maakte het slechtste geval één minuut. Maar een minuut blijft een minuut, en we beseften dat de verplaatsing helemaal niet op iemands pad hoefde te staan.
Er wordt geen werkruimte meer van 1 GB aangemaakt. Dit is dus geen doorlopend proces, maar een eenmalige klus met een vaste lijst werkruimtes. Die binnen het wakker worden doen betekende dat een echt persoon voor elke trage verplaatsing betaalde, en de enige manier waarop we te weten kwamen dat een werkruimte niet verplaatst kon worden, was dat iemand er net op had gewacht.
Dus hebben we de verplaatsing helemaal uit het wakker worden gehaald. Een project openen doet wat het altijd deed. De resterende kleine werkruimtes worden nu als een begeleide batch afgehandeld: niemand wacht erop, en een werkruimte die niet verplaatst kan worden, verschijnt in het rapport van de batch, waar we er naar kunnen kijken, in plaats van voor de neus van de persoon die hem bezit.
Wat we ervan geleerd hebben
- Groter maken is niet altijd mogelijk. Wanneer een platform de grootte bij het aanmaken vastzet, helpt het verhogen van de standaard alleen nieuwe dingen. Houd rekening met de oude.
- "Niemand gebruikt het nog" betekent nog steeds dat iemand wacht. Werk dat wordt gedaan op weg naar een product is werk dat een mens ziet.
- Zet een budget op alles wat op het pad van een gebruiker staat, en stop het werk wanneer het op is. Aan onze kant een time-out zetten terwijl een commando elders blijft draaien, verplaatst het probleem alleen.
- Een eenmalige migratie hoort in een eenmalige taak. Haar verstoppen in alledaagse acties maakt haar goedkoper om te schrijven en duurder om te draaien.
- Test je veiligheidscontroles. Een vergelijking die niets vergelijkt, ziet er precies zo uit als een die geslaagd is.
Als je op Mythex bouwt, hoef je niets te doen: het doel is simpelweg minder werkruimtes die door geheugen heen gaan, met een project openen even snel als voorheen. Hoe werkruimtes pauzeren en wakker worden, staat in de docs onder privéwerkruimte. Voor een ander verhaal over geheugen tekort, zie de out-of-memory-crash die verborgen zat in een voortgangslabel.