Å flytte til større arbeidsområder uten at noen må vente
Hvert Mythex-prosjekt får sitt eget arbeidsområde: en liten skydatamaskin der agenten skriver kode og appens forhåndsvisning kjører. Vi hadde økt nye arbeidsområder fra 1 GB til 2 GB minne, men eldre arbeidsområder ble stående på 1 GB. På dagen vi sjekket, gjaldt det omtrent en fjerdedel av dem. Vår første løsning flyttet et prosjekt til et større arbeidsområde når det ble åpnet neste gang. På første produksjonsdag gjorde det at én person ventet sju minutter. Vi satte en hard tidsgrense på det, og tok så flyttingen ut av det å åpne et prosjekt i det hele tatt.
Hvorfor gamle arbeidsområder forble små
Sandkasseleverandøren vår setter størrelsen på et arbeidsområde når det opprettes, og beholder den gjennom hver pause og gjenopptakelse. Endrer man malen, oppskriften nye arbeidsområder bygges fra, gjelder det bare arbeidsområder som opprettes etter endringen. Ingenting endrer størrelsen på dem som allerede finnes.
Det var viktig. Et av de små arbeidsområdene gikk tom for minne under en git push mens forhåndsvisningen startet, og sluttet å svare i 11 minutter. En publisering feilet på grunn av det.
Første forsøk: flytt prosjektet når det våkner
Arbeidsområder settes på pause når ingen bruker dem, og våkner når prosjektet åpnes. Våkningen virket som riktig øyeblikk for å flytte et prosjekt, fordi ingen jobber i det ennå.
Flyttingen fungerte slik:
- Sjekk størrelsen. Hvis arbeidsområdet er mindre enn 2 GB, flytt det. Hvis størrelsen er ukjent, gjør ingenting.
- Ikke forstyrr en publisering. En publisering leser arbeidsområdets filer, så hvis en kjører, hopper vi over flyttingen.
- Pakk prosjektet. Arkiver alt i prosjektet, inkludert git-historikken, som er hvert lagrepunkt prosjektet har, og appens egen
.env-fil, som tilhører eieren. Men utelat installerte avhengigheter (node_modules), som kan installeres på nytt. - Kopier direkte over. Strøm arkivet fra det gamle arbeidsområdet inn i et nytt 2 GB-arbeidsområde, slik at det aldri må få plass i vår egen servers minne.
- Sammenlign før du bytter. Tell filene, les siste lagrepunkt og tell lagrepunktene i begge arbeidsområdene. Bytt bare hvis alle tre stemmer.
- Behold det gamle ved feil. Ved en hvilken som helst feil eller et avvik kastes det nye arbeidsområdet, og prosjektet åpnes i det gamle, som før.
En detalj i sammenligningen betydde mer enn den ser ut til. Kontrollen kjøres som administratorkontoen, og git nekter å lese et depot som eies av en annen bruker. Den skrev ut ingenting på begge sider. Og «ingenting» var likt «ingenting», så kontrollen besto uten å sammenligne noen historikk i det hele tatt. Vi ba git stole på katalogen, og la til en test slik at dette ikke kan snike seg inn igjen.
Hva som gikk galt første dag
På første produksjonsdag traff pakkingen av ett prosjekt en tidsgrense på fem minutter for en kommando, inne i våkningen. Eieren ventet sju minutter på at arbeidsområdet deres skulle åpne. Og fordi flyttingen hadde feilet, var prosjektet fortsatt lite, så neste åpning ville prøvd igjen og fått dem til å vente igjen.
En migrering som får noen til å vente mens de åpner sitt eget prosjekt, er en dårlig handel. Hele poenget med å gjøre den ved våkning var at ingen skulle merke det.
Andre forsøk: et hardt tidsbudsjett
Samme dag endret vi fire ting:
- Ett minutt for hele flyttingen. Hvert steg (sjekke størrelsen, pakke, opprette det nye arbeidsområdet, kopiere, pakke ut, sammenligne) deler ett felles budsjett på 60 sekunder. Når det er brukt opp, åpnes prosjektet i det gamle arbeidsområdet.
- Stopp arbeidet, ikke bare ventingen. Å gi opp på vår side er ikke nok hvis arkiveringen fortsatt kjører inne i arbeidsområdet eieren er i ferd med å bruke. Hver arkiveringskommando drepes nå inne i arbeidsområdet kort før budsjettet utløper. Hvis det nye arbeidsområdet kommer etter at vi har gitt opp, kastes det.
- Ikke la eieren vente på opprydding. Sletting av den midlertidige arkivfilen skjer nå i bakgrunnen.
- Ikke prøv på nytt ved hver åpning. Et prosjekt som ikke kunne flyttes, lar vi være i fred i 24 timer, slik at en feil koster høyst én forsinkelse om dagen, ikke én per åpning.
Tredje forsøk: ta det ut av våkningen
Det gjorde verste tilfelle til ett minutt. Men et minutt er fortsatt et minutt, og vi innså at flyttingen ikke trengte å være på noens vei i det hele tatt.
Ingen arbeidsområder opprettes lenger på 1 GB. Dette er altså ikke en pågående prosess; det er en engangsjobb med en fast liste over arbeidsområder. Når flyttingen lå inne i våkningen, betalte en ekte person for hver treg flytting, og den eneste måten vi ville finne ut at et arbeidsområde ikke kunne flyttes, var at noen nettopp hadde ventet på det.
Så vi fjernet flyttingen fra våkningen helt. Å åpne et prosjekt gjør det samme som før. De gjenværende små arbeidsområdene håndteres i stedet som en overvåket batch. Ingen venter på den, og et arbeidsområde som ikke vil flyttes, dukker opp i batchens rapport, der vi kan se på det, i stedet for foran eieren.
Det vi tok med oss
- Endring av størrelse er ikke alltid mulig. Når en plattform fastsetter størrelsen ved opprettelse, hjelper det bare nye ting å heve standarden. Planlegg for de gamle.
- «Ingen bruker den ennå» betyr fortsatt at noen venter. Arbeid gjort på vei inn i et produkt er arbeid en person ser på.
- Sett et budsjett på alt som ligger i en brukers vei, og stopp arbeidet når budsjettet er brukt opp. Å tidsavbryte på vår side mens en kommando fortsetter et annet sted, flytter bare problemet.
- En engangsmigrering hører hjemme i en engangsjobb. Å skjule den i hverdagslige handlinger gjør den billigere å skrive og dyrere å kjøre.
- Test sikkerhetskontrollene dine. En sammenligning som ikke sammenligner noe, ser helt ut som en som bestod.
Hvis du bygger på Mythex, er det ingenting du må gjøre: målet er ganske enkelt færre arbeidsområder som går tom for minne, med at åpning av et prosjekt er like raskt som før. Hvordan arbeidsområder settes på pause og våkner, er dekket i dokumentasjonen under privat arbeidsområde. For en annen historie om minne som går tom, se minnekrasjen som gjemte seg i en fremdriftsetikett.