Förstå den inre loopen

Slutförd

Det är inte klart vem som myntade termen "inre loop" i samband med programvaruteknik, men inom Microsoft verkar ordet åtminstone ha fastnat.

Många av de interna team jag arbetar med ser det som något de vill hålla så kort som möjligt - men vad är den inre slingan?

Definitioner

Det enklaste sättet att definiera den inre loopen är den iterativa process som en utvecklare gör när de skriver, skapar och felsöker kod.

Det finns andra saker som en utvecklare gör. Det är rätt uppsättning steg som ska göras upprepade gånger innan de delar sitt arbete med sitt team eller resten av världen.

Diagram som visar koden och byggandet av den inre loopen, och den inre loopen i mitten.

Exakt vad som går in i en enskild utvecklares inre loop beror avsevärt på vilken teknik de arbetar med, vilka verktyg som används och deras preferenser.

Om jag arbetade med ett bibliotek skulle min inre loop innehålla kodning, skapande, testningskörning och felsökning med regelbundna incheckningar till min lokala Git-lagringsplats.

Å andra sidan, om jag gjorde webb frontend arbete, skulle jag förmodligen vara optimerad kring hacking på HTML & JavaScript, paketering och uppdatera webbläsaren (följt av regelbundna incheckningar).

Diagram som visar olika inre loopar som kod, build och test.

De flesta kodbaser består av flera rörliga delar, så definitionen av en utvecklares inre loop på en enskild kodbas kan variera beroende på vad som bearbetas.

Förstå loopen

Stegen i den inre loopen kan grupperas i tre breda aktivitets bucketar – experimentering, feedbackinsamling och skatt.

Om vi går tillbaka till biblioteksutvecklingsscenariot jag nämnde sa jag fyra steg och hur man bucketar dem.

  • Kodning (experimentering)
  • Skapa (feedbacksamling)
  • Testning/felsökning (feedbackinsamling)
  • Incheckning (skatt)

Av alla steg i den inre loopen är kodning den enda som lägger till kundvärde.

Det är viktigt att skapa och testa kod, men i slutändan använder vi dem för att ge utvecklaren feedback om deras skrivning för att se om den ger tillräckligt med värde.

Att lägga in kod i skattehinken är kanske lite hårt, men syftet med bucketen är att kalla ut de aktiviteter som varken lägger till värde eller ger feedback.

Skatt är nödvändig för att fungera. Om det är onödigt arbete är det slöseri och bör elimineras.

Diagram som visar kod, bygga, testa och committa för att hjälpa till att förstå loopen.

Loopoptimering

Efter att ha kategoriserat stegen i loopen är det nu möjligt att göra några allmänna instruktioner:

  • Du vill köra loopen så snabbt som möjligt och att den totala körningstiden för loopen ska vara proportionell mot de ändringar som gjorts.
  • Du vill minimera den tid feedbackinsamlingen tar men maximera kvaliteten på den feedback du får.
  • Du vill minimera den skatt du betalar genom att eliminera den där det är onödigt att köra genom loopen (kan du skjuta upp vissa åtgärder tills du checkar in, till exempel).
  • När ny kod och mer komplexitet läggs till i alla kodbaser ökar också mängden yttre tryck för att öka storleken på den inre loopen. Mer kod innebär fler tester, vilket innebär mer körningstid och långsam körning av den inre loopen.

Anta att du någonsin har arbetat med en stor monolitisk kodbas. I så fall är det möjligt att hamna i en situation där även små ändringar kräver en oproportionerlig tid för att köra stegen för feedbackinsamling i den inre loopen. Det är ett problem, och du bör åtgärda det.

Det finns flera saker som ett team kan göra för att optimera den inre loopen för större kodbaser:

  • Skapa och testa bara vad som har ändrats.
  • Cachelagra mellanliggande byggresultat för att snabba upp till slutförda versioner.
  • Dela upp kodbasen i små enheter och dela binärfiler.

Hur du tar itu med var och en av dem är förmodligen ett blogginlägg.

På Microsoft, för några av våra genuint massiva monolitiska kodbaser.

Vi investerar kraftigt i #1 och #2, but#3 kräver ett särskilt omnämnande eftersom det kan vara ett tveeggat svärd och kan ha motsatsen till den önskade effekten om det görs felaktigt.

Trassliga loopar

För att förstå problemet måste vi se bortom den inre loopen. Låt oss säga att vår monolitiska kodbas har ett programspecifikt ramverk som gör mycket tunga lyft.

Det skulle vara frestande att extrahera det ramverket till en uppsättning paket.

För att göra detta hämtar du koden till en separat lagringsplats (valfritt, men det är vanligtvis så det görs) och konfigurerar sedan en annan CI/CD-pipeline som skapar och publicerar paketet.

En annan pull-request-process skulle också fronta den här separata bygg- och versionspipelinen för att inspektera ändringar innan koden publiceras.

När någon behöver ändra den här ramverkskoden klonar de ned lagringsplatsen, gör ändringar (en separat inre loop) och skickar en PR som övergår arbetsflödet från den inre loopen till den yttre loopen.

Ramverkspaketet skulle sedan vara tillgängligt för att hämtas till beroende program (i det här fallet monoliten).

Diagram som visar kod, skapa, testa och checka in i den yttre loopen.

Till en början kan det gå bra. Men någon gång i framtiden vill du förmodligen utveckla en ny funktion i programmet som kräver att omfattande nya funktioner läggs till i ramverket.

Det är där team som har brutit upp sina kodbaser på suboptimala sätt kommer att börja känna smärta.

Om du måste samvolvera kod i två separata lagringsplatser där ett binärt/biblioteksberoende finns, kommer du att uppleva viss friktion.

I looptermer innehåller den ursprungliga kodbasens inre loop nu (åtminstone tillfälligt) den yttre loopen i den tidigare utbrutna ramverkskoden.

Yttre loopar omfattar skatt, inklusive kodgranskningar, genomsökningspass, binär signering, versionspipelines och godkännanden.

Du vill inte betala för det varje gång du har lagt till en metod i en klass i ramverket och vill nu använda den i ditt program.

Diagram som visar kod-, bygg-, test-, commit- och applåpar för att referera till sammanflätade loopar.

Vad som i allmänhet händer härnäst är en serie lokala hack av utvecklaren för att sy ihop de inre looparna så att de kan gå framåt effektivt - men det blir rörigt snabbt. Du måste betala den yttre loopskatten någon gång.

Det är inte att säga att bryta kod i separata paket är i sig dåligt - det kan fungera utmärkt; du måste göra dessa snitt noggrant.

Avslutande tankar

Det finns ingen lösning för silverkulor för att se till att din inre loop inte börjar sakta ner, men det är viktigt att förstå när det börjar hända, vad orsaken är och arbeta för att åtgärda det.

Beslut som hur du skapar, testar och felsöker arkitekturen påverkar alla utvecklares produktivitet. Att förbättra en aspekt orsakar ofta problem i en annan.