Hållbara Funktioner: Fan Fan I Mönster

0
25

Detta inlägg är ett samarbete mellan mig och mina fantastiska medarbetare, Maxime Rouiller.

Hållbara Funktioner? Wat. Om du är ny till Hållbara, jag föreslår att du börjar här med det här inlägget, som omfattar alla grunderna så att du kan väl dyka i. I detta inlägg, vi kommer att dyka i ett särskilt fall, så att du kan se en Varaktig Funktion mönster på jobbet!

Idag, låt oss tala om Fan, Fan I mönster. Vi kommer att göra det genom att hämta en öppen fråga räknas från GitHub och sedan lagra vad vi får. Här är de reporäntan, där all kod liv som vi kommer att gå igenom i detta inlägg.

Visa Reporäntan

Om Fan In/Fan I Mönster

Vi nämnde detta mönster i föregående artikel, så låt oss se. Skulle du sannolikt nå för detta mönster när du behöver utföra flera funktioner parallellt och sedan utföra någon annan uppgift med dessa resultat. Du kan tänka dig att detta mönster är användbart för en hel del projekt, eftersom det ganska ofta att vi måste göra en sak, baserad på data från några andra källor.

Till exempel, låt oss säga att du är en avhämtning restaurang med massor av beställningar som kommer igenom. Du kan använda detta mönster för att först få ordning och sedan använda det för att räkna ut priser för alla objekt, tillgängligheten av dessa objekt, och se om någon av dem har någon försäljning eller erbjudanden. Kanske försäljningar/erbjudanden är inte värd på samma ställe som din priserna eftersom de styrs av en extern försäljning av företag. Du kanske också måste ta reda på vad din kö för leverans och de som på din personal ska få det baserat på deras geografiska läge.

Det är en hel del samordning! Men skulle du behöver för att sedan fortsätta att samla all denna information för att slutföra beställningen och bearbeta det. Detta är en förenklad, krystat exempel på kurs, men du kan se hur användbart det är att arbeta på ett fåtal saker samtidigt så att de kan sedan användas som en sista funktion.

Här är vad som ser ut som, i abstrakt kod och visualisering

Se Pennan Hållbara Funktioner: Mönster #2, Fan, Fan av Sarah Drasner (@sdras) på CodePen.

const df = require(‘tålig-funktioner”)

modulen.exporten = df(funktion*(ctx) {
const uppgifter = []

// poster till processen samtidigt, läggas till i en array
const taskItems = avkastning ctx.df.callActivityAsync(‘fn1 -‘)
taskItems.forEach(artikel => uppgifter.push(ctx.df.callActivityAsync(‘fn2 -‘ punkt))
avkastning ctx.df.uppgift.alla(uppgifter)

// skicka resultaten till sista funktionen för bearbetning
avkastning ctx.df.callActivityAsync(‘fn3’, aktiviteter)
})

Nu ser vi varför vi skulle vilja använda detta mönster, låt oss dyka in på ett förenklat exempel som förklarar hur man gör.

Konfigurera din miljö för att arbeta med Hållbar Funktioner

Första saker första. Vi har fått för att få miljö för utveckling redo att arbeta med Hållbara Funktioner. Låt oss bryta ner det.

GitHub Personliga Åtkomsttoken

För att köra detta prov, kommer du behöver för att skapa en personlig åtkomsttoken på GitHub. Om du går på ditt konto, foto, öppna menyn och välj Inställningar, sedan Utvecklare inställningar i den vänstra sidofältet. I samma sidebar på nästa skärm klickar du på Personliga åtkomsttokens alternativ.

Sedan ett snabbt kommer upp och du kan klicka på Skapa ny token-knappen. Du bör ge din token ett namn som är logiskt för detta projekt. Som “Hållbara funktioner är bättre än burritos.” Du vet, något standard som.

För omfång/tillstånd alternativ, jag föreslår att du väljer “repor”, som sedan gör det möjligt att klicka på Generera token-knappen och kopiera den token till urklipp. Tänk på att du ska aldrig begå marker. (Det kommer att återkallas om du gör det. Fråga mig inte varför jag vet det.) Om du behöver mer information om att skapa polletter, det finns ytterligare instruktioner här.

Funktioner CLI

För det första, vi kommer att installera den senaste versionen av Azure Funktioner CLI. Vi kan göra så genom att köra detta i terminalen:

npm i-g azure-funktioner-core-verktyg@core-osäkra-perm sant

Gör det osäkra perm flagga freak du? Det gjorde det för mig också. Riktigt vad det gör är att förebygga UID/GID-växling när paketet skript körs, vilket är nödvändigt eftersom paketet i sig är en JavaScript-wrapper runt .NET. Brygga installera utan en sådan flagga är också tillgängliga och mer information om detta finns här.

Tillval: Ställa upp projektet i VS-Kod

Absolut inte nödvändigt, men jag tycker om att arbeta i VS-Kod med Azure Funktioner eftersom det har stor lokal felsökning, som vanligtvis är en smärta med Serverlösa funktioner. Om du inte redan har installerat det, kan du göra så här:

  • Visual Studio-Kod
  • Azure funktioner Förlängning

Upprätta en Gratis Testperiod för Azure och Skapa en Lagring Konto

För att köra detta prov, kommer du behöver för att testa köra en gratis testperiod för Azure. Du kan gå in i portalen och logga i vänster hörn. Du ska göra en ny Blob Storage-konto, och hämta nycklar. Sedan har vi som alla sågat bort, vi är redo att rocka!

Sätta upp Vår Varaktig Funktion

Låt oss ta en titt på reporäntan som vi har satt upp. Vi ska klona eller gaffel det:

git clone https://github.com/Azure-Samples/durablefunctions-apiscraping-nodejs.git

Här är vad som ursprungliga filens struktur är.

(Denna visualisering gjordes från min CLI verktyg.)

I lokal.inställningar.json, ändra GitHubToken till det värde som du tog från GitHub tidigare, och göra samma sak för två förvaring av nycklar och klistra in i nycklarna från lagring-konto som du ställt in tidigare.

Kör sedan:

func installera tillägg
npm jag
func värd börja

Och nu kör vi igång lokalt!

Förstå Orchestrator

Som ni kan se, vi har ett antal mappar inom FanOutFanInCrawler katalog. Funktioner i de kataloger som anges GetAllRepositoriesForOrganization, GetAllOpenedIssues, och SaveRepositories är de funktioner som vi kommer att samordna.

Här är vad vi ska göra:

  • Den Orchestrator kommer att sparka igång den GetAllRepositoriesForOrganization-funktion, där vi kommer att passera i organisationens namn, hämtade från getInput() från Orchestrator_HttpStart funktion
  • Eftersom det är sannolikt att vara mer än en repo, vi ska först skapa en tom array, sedan loopa igenom alla repor och köra GetOpenedIssues, och driva dem på rad. Vad vi kör här kommer alla eld samtidigt för att den inte inom avkastningen i iterator
  • Sedan ska vi vänta på att alla uppgifter att avsluta verkställande och slutligen kalla SaveRepositories som kommer att lagra alla resultat i Blob Storage

Sedan andra funktioner är ganska standard, låt oss gräva i att Orchestrator för en minut. Om vi ser inuti Orchestrator-katalog, kan vi se att det har en ganska traditionell installation för en funktion med index.js och funktion.json-filer.

Generatorer

Innan vi går in på Orchestrator, låt oss ta en mycket kort sida tur till generatorer, eftersom du inte kommer att kunna förstå resten av koden utan dem.

En generator är inte det enda sättet att skriva denna kod! Det kunde ske med andra asynkron JavaScript mönster också. Det råkar vara så att detta är en ganska ren och lättläst sätt att skriva på, så låt oss titta på det riktigt snabbt.

funktion* generator(jag) {
avkastningen i++;
avkastningen i++;
avkastningen i++;
}

var gen = generator(1);

konsolen.log(gen.next (nästa).value); // 1
konsolen.log(gen.next (nästa).value); // 2
konsolen.log(gen.next (nästa).value); // 3
konsolen.log(gen.nästa ()); / / {- värde: odefinierad, och gjort: true}

Efter den första lilla asterisk följande funktion* du kan börja använda avkastningen sökord. Ringer en generator fungerar inte köra hela funktionen i sin helhet; en iterator objektet returneras i stället. Nästa () – metoden kommer att gå över dem en efter en, och vi kommer att få ett föremål som berättar både värdet och gjort — som kommer att vara en boolean om vi är klar gå igenom alla av avkastningen uttalanden. Du kan se i exemplet ovan att för den sista .nästa () – anropet, ett objekt är tillbaka där gjort är sant, att låta oss veta att vi har vm genom alla värden.

Orchestrator-kod

Vi ska börja med att kräva uttalande att vi kommer att behöva för att det ska fungera:

const df = require(‘tålig-funktioner”)

modulen.exporten = df(funktion*(sammanhang) {
// våra orchestrator-kod kommer att gå här
})

Det är värt att notera att den asterisk det kommer att skapa en iterator funktion.

För det första, vi kommer att få organisationen namn från Orchestrator_HttpStart funktion och få alla repor för att organisationen med GetAllRepositoriesForOrganization. Obs vi använder avkastning inom arkiv uppdrag att göra funktionen utför i ordning.

const df = require(‘tålig-funktioner”)

modulen.exporten = df(funktion*(sammanhang) {
var organizationName = sammanhanget.df.getInput()
var förråden = avkastning sammanhang.df.callActivityAsync(
‘GetAllRepositoriesForOrganization’,
organizationName
)
})

Då kommer vi att skapa en tom array heter utgång, skapa en for-loop från den array vi fick som innehåller alla organisationens repor och använda det för att driva frågor i en array. Observera att vi inte använder avkastningen här, så att de använder alla samtidigt istället för att vänta en efter en.

const df = require(‘tålig-funktioner”)

modulen.exporten = df(funktion*(sammanhang) {
var organizationName = sammanhanget.df.getInput()
var förråden = avkastning sammanhang.df.callActivityAsync(
‘GetAllRepositoriesForOrganization’,
organizationName
)

var output = []
for (var i = 0; i < förråd.längd; i++) {
utgång.push(
sammanhanget.df.callActivityAsync(‘GetOpenedIssues’, arkiv[i])
)
}

})

Slutligen, när alla dessa avrättningar är klar, vi kommer att lagra resultaten och pass som i till SaveRepositories funktion, vilket kommer att spara dem till Blob Storage. Då vi kommer tillbaka unikt ID för den instans (sammanhang.instanceId).

const df = require(‘tålig-funktioner”)

modulen.exporten = df(funktion*(sammanhang) {
var organizationName = sammanhanget.df.getInput()
var förråden = avkastning sammanhang.df.callActivityAsync(
‘GetAllRepositoriesForOrganization’,
organizationName
)

var output = []
for (var i = 0; i < förråd.längd; i++) {
utgång.push(
sammanhanget.df.callActivityAsync(‘GetOpenedIssues’, arkiv[i])
)
}

const resultat = direktavkastning sammanhang.df.Uppgift.alla(utgång)
avkastning sammanhang.df.callActivityAsync(‘SaveRepositories’, resultat)

tillbaka sammanhang.instanceId
})

Nu har vi fått alla de steg som vi måste hantera alla våra funktioner med denna enda orchestrator!

Distribuera

Nu till den roliga biten. Låt oss distribuera! 🚀

Distribuera komponenter, Azure kräver att du installerar Azure-CLI och logga in med det.

Först kommer du behöver för att tillhandahålla tjänsten. Titta in i bestämmelsen.ps1-fil som tillhandahålls för att bekanta dig med de resurser som vi kommer att skapa. Sedan kan du köra filen med den tidigare genererade GitHub token så här:

.bestämmelsen.ps1 -githubToken <TOKEN> -resourceGroup <ResourceGroupName> -storageName <StorageAccountName> -functionName <FunctionName>

Om du inte vill installera PowerShell, du kan också ta kommandon i bestämmelsen.ps1 och köra det manuellt.

Och där har vi det! Våra Hållbara Funktionen är igång.