Langlebig Funktionen: Fan-Out Fan-In-Muster

0
24

Dieser Beitrag ist eine Zusammenarbeit zwischen mir und meinem awesome Mitarbeiter, Rouiller Maxime.

Dauerhafte Funktionen? Wat. Wenn Sie neu sind, um Langlebige, ich schlage vor, Sie starten hier mit diesem Beitrag, das deckt alles wesentliche, so dass Sie ordnungsgemäß Tauchen Sie ein in. In diesem post, wir gehen Tauchen Sie ein in einen bestimmten Anwendungsfall, so dass Sie sehen können, eine Dauerhafte Funktion Muster bei der Arbeit!

Heute sprechen wir über das Fan-Out, Fan-In – Muster. Wir werden dies durch die Abfrage eine offene Frage für die Zählung von GitHub und dann zu speichern, was wir bekommen. Hier ist das repo, wo alle Kodex Leben, dass wir zu Fuss durch in diesem Beitrag.

Ansicht Repo

Über die Fan-Out/Fan-In-Muster

Wir haben kurz erwähnt, dass dieses Muster in dem vorangegangenen Artikel, so lassen Sie uns überprüfen. Sie würden wahrscheinlich erreichen, die für dieses Muster, wenn Sie ausführen müssen, die mehrere Funktionen parallel und führen Sie dann eine andere Aufgabe, mit diesen Ergebnissen. Sie können sich vorstellen, dass dieses Muster ist nützlich für eine ganze Reihe von Projekten, weil es ziemlich oft vor, dass wir eine Sache machen, basierend auf Daten von ein paar anderen Quellen.

Zum Beispiel, sagen wir, Sie sind ein imbiss-restaurant mit einer Tonne von Bestellungen kommen durch. Verwenden Sie dieses Muster, um zunächst den Auftrag bekommen, verwenden Sie dann, um herauszufinden, die Preise für alle Gegenstände, die Verfügbarkeit dieser Elemente, und sehen, wenn irgendwelche von Ihnen haben keine Verkäufe oder Angebote. Vielleicht ist der Verkauf/Angebote sind nicht zu Gast in den gleichen Ort, wie Sie Ihre Preise, weil Sie kontrolliert werden von einem externen Vertriebs-Firma. Sie müssen möglicherweise auch, um herauszufinden, was Ihre Lieferung queue ist wie und die auf Ihre Mitarbeiter es bekommen sollten, basierend auf Ihrem Standort.

Das ist viel Koordination! Aber Sie müssten dann sammeln Sie alle diese Informationen, um die Bestellung abzuschließen und zu verarbeiten. Dies ist ein Vereinfachtes, Beispiel erfundene natürlich, aber Sie können sehen, wie nützlich es ist, zu arbeiten, auf ein paar Dinge gleichzeitig, so dass Sie dann verwendet werden kann, durch eine Letzte Funktion.

Hier ist, wie das aussieht, wird im abstrakten code und Visualisierung

Finden Sie den Stift, Langlebig Funktionen: Muster #2, Fan-Out, Fan-In von Sarah Drasner (@sdras) auf CodePen.

const df = require(‘robust-Funktionen”)

– Modul.Exporte = df (- Funktion*(ctx) {
const tasks = []

// Elemente zu verarbeiten und gleichzeitig in ein array eingefügt
const taskItems = Ertrag ctx.df.callActivityAsync(‘fn1’)
taskItems.forEach(item = > “Aufgaben”.push(ctx.df.callActivityAsync(‘fn2’, Element))
Ausbeute ctx.df.Aufgabe.alle(Aufgaben)

// senden Sie die Ergebnisse zur letzten Funktion für die Verarbeitung
Ausbeute ctx.df.callActivityAsync(‘fn3’, Aufgaben)
})

Nun, wir sehen, warum würden wir wollen, verwenden Sie dieses Muster, lassen Sie uns Tauchen Sie ein in ein Vereinfachtes Beispiel, das erklärt, wie.

Einrichten Ihrer Umgebung für die Arbeit mit Dauerhaften Funktionen

Die ersten Dinge zuerst. Wir haben-Entwicklungsumgebung bereit zu arbeiten mit Dauerhaften Funktionen. Lassen Sie uns brechen, dass nach unten.

GitHub Persönlichen Zugangs-Token

Um dieses Beispiel auszuführen, benötigen Sie einen persönlichen Zugangs-token in GitHub. Wenn Sie gehen, die unter Ihrem Konto Foto, öffnen Sie das dropdown-Menü und wählen Sie Einstellungen und dann Entwickler-Einstellungen ” in der linken Seitenleiste. In der gleichen sidebar auf dem nächsten Bildschirm, klicken Sie auf Persönliche Zugangs-Token-option.

Dann eine Eingabeaufforderung wird kommen, und Sie können klicken Sie auf die Erzeugung neuer token button. Sollten Sie Ihren token ein name, der Sinn macht, für dieses Projekt. Wie “Haltbar-Funktionen sind besser als burritos.” Sie wissen, etwas standard, wie die.

Für die Bereiche, die/permission option, schlage ich vor, die Wahl “repos”, die dann ermöglicht, um auf das Generieren von token-Taste und kopieren Sie den token in die Zwischenablage zu kopieren. Bitte beachten Sie, dass sollten Sie nie Begehen Sie Ihre token. (Es wird widerrufen, wenn Sie tun. Mich Fragen, warum ich weiß, dass.) Wenn Sie weitere Informationen zum erstellen von Token, es gibt noch weitere Anweisungen hier.

Funktionen CLI

Zuerst installieren wir die neueste version des Azure-Funktionen CLI. Wir können dies tun, indem Sie diesen in unserem terminal:

npm i-g azure-Funktionen-core-tools@core –unsafe-perm true

Hat die unsichere perm Flagge Sie ausflippen? Es hat sich für mich als gut. Wirklich, was es tut, ist zu verhindern UID/GID wechseln, wenn Paket-Skripte ausführen, die notwendig ist, weil das Paket selbst ist ein JavaScript-wrapper .NET. Brew installieren ohne solch ein flag ist auch verfügbar, und mehr Informationen über das, was hier ist.

Optional: einrichten des Projektes in VS-Code

Absolut nicht notwendig, aber ich arbeite gerne im VS-Code mit Azure-Funktionen, denn es hat eine große lokale Debuggen, der in der Regel ein Schmerz mit Serverlose Funktionen. Wenn Sie nicht haben es bereits installiert haben, können Sie dies hier tun:

  • Visual Studio Code
  • Azure-Funktionen-Erweiterung

Eine Kostenlose Testversion für Azure und Erstellen Sie ein speicherkonto

Um dieses Beispiel auszuführen, müssen Sie zum testen eine Kostenlose Testversion für Azure. Gehen Sie auf das portal und melden Sie sich in der linken Ecke. Sie machen einen neuen Blob-Storage-account und abrufen der Schlüssel. Da haben wir das alles squared entfernt, wir sind bereit zu rocken!

Unsere Dauerhafte Funktion

Werfen wir einen Blick auf die repo, die wir eingerichtet haben. Wir werden Klonen oder Gabel:

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

Hier ist, was das ursprüngliche Datei-Struktur ist wie.

(Diese Darstellung wurde aus meiner CLI-tool.)

In lokalen.Einstellungen.json ändern GitHubToken den Wert, den Sie packte aus GitHub früher, und tun das gleiche für die beiden Speicher Schlüssel — fügen Sie den Schlüssel aus dem storage-Konto, das Sie zuvor eingerichtet haben.

Dann ausführen:

func-Erweiterungen installieren
npm i
func host starten

Und jetzt sind wir vor Ort läuft!

Das Verständnis der Orchestrator

Wie Sie sehen können, haben wir eine Reihe von Ordnern innerhalb des FanOutFanInCrawler-Verzeichnis. Die Funktionen, die in den Verzeichnissen aufgeführt GetAllRepositoriesForOrganization, GetAllOpenedIssues, und SaveRepositories sind die Funktionen, die wir zu koordinieren.

Hier ist, was wir machen werden:

  • Der Orchestrator wird kick-off der GetAllRepositoriesForOrganization Funktion, wo wir dann den pass in den Namen der Organisation, abgerufen getInput() aus der Funktion Orchestrator_HttpStart
  • Da dies wahrscheinlich mehr sein, als ein repo, wir werden erstellen Sie zuerst ein leeres array ist, dann eine Schleife durch alle repos und führen GetOpenedIssues, und schieben diese auf das array. Was wir sind hier alle Feuer gleichzeitig, weil es nicht innerhalb der Ausbeute in der “iterator”
  • Dann werden wir warten, bis alle die Aufgaben zu beenden, ausführen, und schließlich rufen SaveRepositories die Speicherung aller Ergebnisse in einem Blob-Speicher

Da die anderen Funktionen sind ziemlich standard, lassen Sie uns in Graben, Orchestrator für eine minute. Wenn wir den Blick in das Orchestrator-Verzeichnis, können wir sehen, es hat einen Recht klassischen Aufbau für eine Funktion mit index.js und-Funktion.json-Dateien.

Generatoren

Bevor wir Tauchen in den Orchestrator, nehmen wir eine sehr kurze tour Seite in Generatoren, weil Sie nicht in der Lage zu verstehen, den rest des Codes, ohne Sie.

Ein generator ist nicht der einzige Weg, um dieser code zu schreiben! Es konnte erreicht werden, die mit anderen asynchronous JavaScript patterns. Es passiert einfach so, dass dies eine ziemlich saubere und lesbare Art und Weise zu schreiben, so schauen wir uns das wirklich schnell.

Funktion* generator(i) {
Ausbeute i++;
Ausbeute i++;
Ausbeute i++;
}

var gen = generator(1);

console.log(gen.next().Wert); // 1
console.log(gen.next().Wert); // 2
console.log(gen.next().Wert); // 3
console.log(gen.next()); // {value: undefined, done: true}

Nach der ersten kleinen Sternchen folgende Funktion* können Sie beginnen, verwenden Sie das yield-Schlüsselwort. Aufrufen einer generator-Funktion nicht ausgeführt wird die gesamte Funktion in Ihrer Gesamtheit; ein iterator-Objekt zurück statt. Die next () – Methode gehen über Sie eins nach dem anderen, und wir erhalten ein Objekt, das uns sagt, sowohl den Wert und fertig — das wird ein boolean, ob wir fertig sind, gehen durch alle den yield-Anweisungen. Sie sehen im obigen Beispiel, für den letzten .next () – Aufruf, wird ein Objekt zurückgegeben, wo getan ist wahr, lassen Sie es uns wissen, wir haben iteriert über alle Werte.

Orchestrator-code

Wir beginnen mit der require-Anweisung die wir brauchen für diese zu arbeiten:

const df = require(‘robust-Funktionen”)

– Modul.Exporte = df (- Funktion*(context) {
// unsere orchestrator-code gehen Sie hier
})

Es ist erwähnenswert, dass das Sternchen es wird eine iterator-Funktion.

Erste, erhalten wir den Namen der Organisation aus dem Orchestrator_HttpStart Funktion und erhalten Sie alle repos für die Organisation mit GetAllRepositoriesForOrganization. Hinweis: wir verwenden Ausbeute innerhalb der repositories Zuordnung, um die Funktion auszuführen, in der Reihenfolge.

const df = require(‘robust-Funktionen”)

– Modul.Exporte = df (- Funktion*(context) {
var organizationName = Kontext.df.getInput()
var-repositories = Ertrag Kontext.df.callActivityAsync(
‘GetAllRepositoriesForOrganization’,
organizationName
)
})

Dann werden wir ein leeres array mit dem Namen der Ausgabe, erstellen Sie eine for-Schleife aus dem array haben wir mit allen von der Organisation repos, und verwenden Sie diese, um die push-Probleme in das array. Beachten Sie, dass wir nicht verwenden Ausbeute hier so, dass Sie alle gleichzeitig ausgeführt werden, anstatt zu warten, eine nach der anderen.

const df = require(‘robust-Funktionen”)

– Modul.Exporte = df (- Funktion*(context) {
var organizationName = Kontext.df.getInput()
var-repositories = Ertrag Kontext.df.callActivityAsync(
‘GetAllRepositoriesForOrganization’,
organizationName
)

var output = []
for (var i = 0; i < repositories.length; i++) {
Ausgabe.push(
Kontext.df.callActivityAsync(‘GetOpenedIssues’, repositories[i])
)
}

})

Schließlich, wenn alle diese Ausführungen sind fertig, wir speichern die Ergebnisse und übergeben Sie, in der SaveRepositories-Funktion, die Sie speichern Sie Sie in den Blob-Speicher. Dann kommen wir zurück auf die eindeutige ID der Instanz (Kontext.instanceId).

const df = require(‘robust-Funktionen”)

– Modul.Exporte = df (- Funktion*(context) {
var organizationName = Kontext.df.getInput()
var-repositories = Ertrag Kontext.df.callActivityAsync(
‘GetAllRepositoriesForOrganization’,
organizationName
)

var output = []
for (var i = 0; i < repositories.length; i++) {
Ausgabe.push(
Kontext.df.callActivityAsync(‘GetOpenedIssues’, repositories[i])
)
}

const Ergebnis = Ertrag-Zusammenhang.df.Aufgabe.alle(output -)
Ausbeute Kontext.df.callActivityAsync(‘SaveRepositories’, Ergebnis)

return context.instanceId
})

Nun haben wir alle Schritte, die wir brauchen, um zu verwalten alle unsere Funktionen mit dieser single orchestrator!

Bereitstellen

Jetzt zum lustigen Teil. Let ‘ s bereitstellen! 🚀

Bereitstellen von Komponenten, Azure erfordert die Installation der Azure-CLI und anmelden.

Erste, Sie benötigen, um die Bereitstellung des service. Schauen Sie in die Bestimmung.ps1-Datei zur Verfügung gestellt machen Sie sich mit den Ressourcen, die wir erstellen werden. Dann auszuführen, können Sie die Datei mit der zuvor generierten GitHub-token wie diese:

.Bestimmung.ps1 -githubToken <TOKEN> -resourceGroup <ResourceGroupName> -storageName <StorageAccountName> -functionName <FunctionName>

Wenn Sie nicht möchten, installieren Sie PowerShell, können Sie auch die Befehle in Bereitstellung.ps1 und führen Sie es manuell.

Und da haben wir es! Unsere Dauerhafte Funktion ist und läuft.