Direkt zum Hauptinhalt

Eine Funktion ausführen

Ziel​

Etwas soll geschehen, ohne dass jemand einen Datensatz speichert: eine Erinnerung jede Nacht, ein Stapel Datensätze, der jede Stunde aufgeräumt wird, eine lange Arbeit, die man von Hand startet und laufen lässt. Und hinterher soll man genau nachlesen können, was jede Ausführung getan hat.

Warum es das gibt​

Alles andere, was die Skripte einer Lösung tun, beginnt mit dem Speichern durch jemanden — ein Plug-in-Schritt läuft in einem Schreibvorgang, eine benutzerdefinierte API, wenn ein anderes System sie aufruft. Manche Arbeit gehört aber zu keinem Schreibvorgang: Sie hängt an einer Uhrzeit oder an einem Stapel, der zu groß ist, als dass jemand darauf warten könnte.

Eine Funktion ist ein BS-Lang-Skript, das der Funktionsdienst selbst ausführt — in einem eigenen Prozess und so lange, wie Sie es erlauben. Sie ist eine Komponente Ihrer Lösung wie ein Formular oder ein Skript: in Dev geschrieben und im Lösungspaket nach Test und Production gebracht.

Bevor Sie beginnen​

  • Eine Lösung mit einem Herausgeber.
  • Die Tabellen, die Ihre Funktion liest und schreibt.
  • Ruft sie einen externen Dienst auf oder sendet sie E-Mails: die Umgebungsvariable, die ihn benennt — siehe Einen externen Dienst aus einem Skript aufrufen.

Schritte​

  1. Öffnen Sie Ihre Lösung, wählen Sie in der linken Leiste Funktionen und dann Neu.
  2. Schreiben Sie auf der Registerkarte Skript, was die Funktion tut. Sie kann Datensätze und Dateien lesen und schreiben, externe Dienste aufrufen und Ihre Lösungsskripte mit import einbinden — dasselbe wie ein Plug-in-Schritt. Das Auge am Ende der Registerleiste listet alles auf, was Sie aufrufen können.
  3. Geben Sie ihr auf der Registerkarte Einstellungen einen Anzeigenamen. Der logische Name füllt sich selbst aus.
  4. Legen Sie fest, wann sie läuft. Jede Funktion lässt sich von Hand ausführen. Soll sie auch von selbst laufen, aktivieren Sie Läuft nach Zeitplan und wählen ein Intervall — alle 15 Minuten, alle 6 Stunden, jeden Tag. Bei einem täglichen Zeitplan können Sie eine Uhrzeit und deren Zeitzone festlegen.
  5. Legen Sie die maximale Laufzeit fest — wie lange eine Ausführung dauern darf, bevor sie gestoppt wird. Standard sind 15 Minuten, höchstens ein Tag.
  6. Wählen Sie Speichern. Ein Skript, das sich nicht parsen lässt, wird sofort abgelehnt, mit der fehlerhaften Zeile.
  7. Wählen Sie Jetzt ausführen. Die Registerkarte Ausführungen öffnet sich und verfolgt die Ausführung: In Warteschlange, Läuft, dann wie sie endete. Wählen Sie die Ausführung, um ihr Protokoll zu lesen.

Ein Protokoll schreiben​

Während eine Funktion läuft, schaut niemand zu — ihr Protokoll ist der Weg herauszufinden, was sie getan hat.

var due = queryRecords('par_membership', 'par_reminder_state', 'due');
log('Reminders due: ' + toJson(due.length()));

for (var i: int = 0; i < due.length(); i++) {
updateRecord('par_membership', due[i].id, { par_reminder_state: 'sent' });
log(due[i]);
}
  • Text wird geschrieben, wie er ist, eine Zahl, wie Sie sie schreiben würden, und ein Datensatz oder eine Liste als JSON — log(due[i]) zeigt also den ganzen Datensatz, wie die Ausführung ihn sah.
  • Die Registerkarte Ausführungen zeigt die Zeilen schon während der Ausführung, wenige Sekunden verzögert.
  • Eine Ausführung behält höchstens 5.000 Zeilen; die letzte behaltene sagt, dass das Protokoll voll ist.
  • Protokollzeilen behalten auf der Registerkarte Einstellungen schaltet das Protokoll ab. log funktioniert weiter und behält nichts — Sie müssen das Skript also nie ändern, um es stumm zu schalten oder wieder einzuschalten.

Eine Ausführung absichtlich beenden​

stop('reason') beendet die Ausführung an dieser Stelle als Erfolg mit Begründung:

if (due.length() == 0) {
stop('Nobody is due a reminder tonight.');
}

Das Ergebnis der Ausführung zeigt diesen Satz. Das ist kein Fehlschlag, und die Liste zeigt es auch nicht so.

Eine Funktion aus einem Skript starten​

Eine Funktion braucht keine Uhr. Eine Custom API, ein Plugin-Schritt oder eine andere Funktion kann sie mit startFunction starten, ihr eine Eingabe mitgeben und bekommt die ID der Ausführung sofort zurück — die Arbeit geschieht danach im Functions-Dienst. So wird eine Anfrage, die eine Stunde Arbeit braucht, in einem Augenblick beantwortet.

// A Custom API: POST reports { "period": "2026-10" }
var run = startFunction('par_sales_report', { period: getInput('period') });
setStatus(202);
setOutput('run', run);
// The function
var asked = functionInput();
// … the long work …
setResult({ period: asked.period, total: total });
// A second Custom API: GET reports/runs/{run}
var run = functionRun(getInput('run'));
if (run == null) { setStatus(404); } else { setOutput('status', run.status); setOutput('report', run.result); }
  • startFunction(name, input) gibt die ID der Ausführung zurück. Die Eingabe — ein Datensatz, eine Liste, ein Wert oder null — liest die Funktion mit functionInput(). Eine Ausführung, die ihr Zeitplan oder Run now gestartet hat, hat keine Eingabe und liest null.
  • setResult(value) ist, was die Ausführung zurückgibt. Nur der letzte Wert wird behalten, und nur, wenn die Ausführung erfolgreich ist. Halten Sie ihn klein — eine Zusammenfassung oder den Schlüssel einer Datei —, denn er wird jedes Mal gelesen, wenn jemand nach dem Stand fragt.
  • functionRun(id) gibt { id, function, status, outcome, result, queuedAt, startedAt, finishedAt } zurück, oder null, wenn es keine solche Ausführung gibt.
  • Aus einem Plugin-Schritt wird die Ausführung innerhalb des Schreibvorgangs gestartet: Wird der Schreibvorgang abgelehnt, startet sie nie.
  • Von einem Skript gestartete Ausführungen unterliegen nicht der Regel „eine zur Zeit“. Zwei Personen, die gleichzeitig fragen, bekommen zwei Ausführungen. Die Regel gilt für den Zeitplan und Run now.
  • Auf der Registerkarte Runs steht bei einer solchen Ausführung Wie sie gestartet wurde: Ein Skript, und wenn Sie sie auswählen, sehen Sie Eingabe und Ergebnis über dem Protokoll.
  • Gibt es die Funktion nicht oder ist sie ausgeschaltet, hält startFunction das Skript mit dem Grund an — dem Aufrufer wird also nie gesagt, eine Arbeit habe begonnen, die nicht begonnen hat.

Benachrichtigt werden, wenn sie endet​

Ein Aufrufer, der nicht immer wieder nachfragen will, kann sich benachrichtigen lassen. startFunctionWithCallback ist startFunction mit einem Argument mehr: dem Namen einer Umgebungsvariablen, die die zu benachrichtigende Adresse enthält. Wenn die Ausführung endet – wie auch immer –, wird ihr Ergebnis einmal dorthin gesendet.

// A Custom API: POST totals
var run = startFunctionWithCallback('par_invoice_totals', null, 'par_totals_done');
setStatus(202);
setOutput('run', run);

Was ankommt:

{ "run": "…", "function": "par_invoice_totals", "status": "Succeeded",
"outcome": null, "result": { "invoices": 3, "total": 165.5 }, "finishedAt": "…" }
  • Nie eine URL im Skript. Das dritte Argument nennt eine Umgebungsvariable, genau wie bei callService; wohin sie zeigt, entscheidet die Administration je Umgebung. Ein Name, den die Lösung nicht deklariert, hält das Skript an, bevor etwas startet.
  • Einmal gesendet, nicht wiederholt. Auf der Registerkarte Ausführungen zeigt die gewählte Ausführung ihre Rückmeldung und was daraus wurde – Delivered (HTTP 200), der Status, mit dem der Dienst antwortete, oder warum er nicht erreichbar war. Wer sie verpasst hat, kann die Ausführung weiterhin mit functionRun lesen.
  • Der Status der Ausführung hängt nicht davon ab. Eine Ausführung, die ihre Arbeit getan hat, ist erfolgreich, auch wenn der zu benachrichtigende Dienst nicht erreichbar ist.

Eine Datei schreiben​

Eine Funktion kann mit denselben Aufrufen wie eine Custom API in den Objektspeicher schreiben — putFile, putFileAs, getFile, listFiles und deleteFile —, obwohl niemand angemeldet ist, während sie läuft.

var key = 'orders/' + today() + '.csv';
putFileAs('par-order-exports', key, csv, 'text/csv');
setResult({ bucket: 'par-order-exports', key: key, rows: orders.length() });
  • Die Datei landet im Speicher Ihrer Organisation und zählt gegen deren Speicherkontingent. Ein Schreibvorgang, der das Kontingent überschreiten würde, lässt den Lauf fehlschlagen.
  • Unter Verwaltung → Speicher steht als Hochlader function:<name> — die Funktion hat die Datei geschrieben, nicht wer Jetzt ausführen gedrückt hat.
  • So gibt eine Funktion mehr als eine Zusammenfassung zurück: Schreiben Sie die Daten in eine Datei und legen Sie deren Schlüssel ins Ergebnis.
  • Nichts löscht alte Dateien für Sie. Eine Funktion, die jede Nacht eine schreibt, sollte die nicht mehr benötigten löschen, wie es das Beispiel functions-nightly-export-to-storage tut.

Wie eine Ausführung endet​

StatusWas geschah
ErfolgreichDas Skript lief zu Ende oder stoppte sich mit stop(...)
FehlgeschlagenDas Skript warf einen Fehler, ein Schreibvorgang wurde abgelehnt, die maximale Laufzeit wurde überschritten oder der Dienst stoppte währenddessen. Das Ergebnis sagt, was davon
AbgebrochenJemand hat Ausführung abbrechen gewählt

Eine fehlgeschlagene Ausführung wird nie für Sie wiederholt. Eine Funktion kann lange laufen, und neunundzwanzig Minuten Arbeit ohne Ihr Wissen zu wiederholen, wäre schlimmer als aufzuhören. Lesen Sie, warum sie fehlschlug, beheben Sie das Nötige und wählen Sie Jetzt ausführen.

Prüfen, ob es funktioniert hat​

  • Die Ausführung ist Erfolgreich, und ihr Protokoll sagt, was Sie erwartet haben.
  • Öffnen Sie einen Datensatz, den die Funktion geändert hat, und sehen Sie in seinen Überwachungsverlauf: Die Änderung ist der Funktion zugeschrieben, nicht einer Person. Eine Funktion läuft als Plattform, ohne jemanden dahinter.
  • Bei einer geplanten Funktion ist Nächste Ausführung auf der Registerkarte Einstellungen der nächste Zeitpunkt, zu dem sie von selbst läuft.

Gut zu wissen​

  • Immer nur eine Ausführung. Solange eine wartet oder läuft, wird „Jetzt ausführen“ abgelehnt, und ein fälliger Zeitplan wird bis zum nächsten Mal übersprungen. Ein nächtlicher Lauf, der zu lange dauerte, startet nie zweimal über dieselben Datensätze.
  • „Jetzt ausführen“ führt den gespeicherten Stand aus und ist bei ungespeicherten Änderungen nicht verfügbar.
  • Aus ist aus. Eine ausgeschaltete Funktion läuft weder nach Zeitplan noch von Hand.
  • Ein geändertes Skript verschiebt den Zeitplan nicht; ein geänderter Zeitplan schon.
  • Ausführung abbrechen stoppt ein laufendes Skript innerhalb weniger Sekunden — auch eine Schleife, die keinen Datensatz berührt.
  • Jede Funktion behält ihre 200 jüngsten Ausführungen.

Fehlerbehebung​

SymptomWahrscheinliche UrsacheLösung
Jetzt ausführen ist ausgegrautUngespeicherte Änderungen, oder die Funktion ist ausgeschaltetSpeichern; einschalten
Diese Funktion läuft bereitsEine Ausführung wartet oder läuftWarten, oder sie wählen und Ausführung abbrechen
Fehlgeschlagen: Stopped after … minutesMaximale Laufzeit überschrittenMaximale Laufzeit erhöhen, oder jede Ausführung weniger tun lassen
Fehlgeschlagen, weil der Dienst währenddessen stoppteDer Dienst wurde neu gestartetErneut ausführen
Das Protokoll ist leerProtokollzeilen behalten ist aus, oder das Skript ruft log nirgends aufEinschalten; log(...) ergänzen
Der Lauf schlug fehl: There is not enough storage leftDas Speicherkontingent der Organisation ist aufgebrauchtLöschen Sie nicht mehr benötigte Dateien oder wechseln Sie in einen größeren Tarif
Der Lauf schlug fehl: Object storage is not configured for the Functions serviceDie Installation hat dem Functions-Dienst keine Speichereinstellungen gegebenFragen Sie Ihre Administration

Siehe auch​