timeoutSeconds begrenzt (maximal 900 Sekunden). Alles, was in diesem Zeitfenster nicht abgeschlossen werden kann – ein vollständiger Re-Sync, ein Fan-out pro Datensatz, eine Drittanbieter-API, die dich rate-limitiert – muss in kleinere Läufe aufgeteilt werden.
enqueueJob macht genau das: Es weist die Twenty-Worker an, eine der Logikfunktionen deiner App später, in einem eigenen Prozess, mit eigenem Timeout-Budget auszuführen. Der Aufrufer kehrt sofort zurück.
Einen Lauf in die Warteschlange stellen
ImportiereenqueueJob aus twenty-sdk/logic-function und gib den universalIdentifier der Logikfunktion an, die du ausführen möchtest.
src/logic-functions/sync-all-contacts.ts
payload als Handler-Argument, genau wie jeder andere Trigger. Sie muss zur gleichen Applikation gehören wie der Aufrufer — das Einreihen der Funktion einer anderen App wird mit Logic function not found abgelehnt.
enqueueJob kehrt zurück, sobald der Job akzeptiert wurde, nicht wenn er ausgeführt wurde. Sie gibt nicht das Ergebnis des Ziels zurück — lasse das Ziel das Ergebnis in den Key-Value-Speicher oder in einen Workspace-Datensatz schreiben, wenn du es wieder auslesen musst.Job-Optionen
Priorität ist noch nicht konfigurierbar. Eingereihte Jobs laufen immer mit der niedrigsten Priorität, sodass Plattformarbeit niemals hinter Applikationsjobs verzögert wird. Steuerung der Priorität kommt bald.
Verwendung: eine lange Synchronisation seitenweise verarbeiten
Die klassische Form ist eine Funktion, die sich selbst mit dem nächsten Cursor in die Warteschlange stellt. Jeder Lauf erledigt eine Seite Arbeit deutlich innerhalb seines eigenen Timeouts, und die Kette endet, wenn nichts mehr übrig ist.src/logic-functions/sync-contacts-page.ts
Aufteilung pro Datensatz
Wenn die Arbeit natürlich pro Element anfällt, reihe einen Job pro Element ein und lasse die Worker sie parallel verarbeiten, anstatt inline zu iterieren.Bewährte Vorgehensweisen für langlaufende Arbeit
Zwei Regeln decken fast jeden langen Job ab: rekursiv statt in einer Schleife arbeiten und pro Lauf einen begrenzten Chunk verarbeiten. Ein Lauf, der versucht, alles zu erledigen, ist der Fehlerfall — er erreicht das Timeout, und bei einem Retry startet er den gesamten Vorgang erneut von vorn. Bestimme stattdessen die Größe eines Chunks so, dass er bequem innerhalb vontimeoutSeconds fertig wird, speichere deine Position und reihe den nächsten Lauf ein.
src/logic-functions/enrich-companies-batch.ts
- Lege die Chunk-Größe anhand des langsamsten Elements fest, nicht anhand des Durchschnitts.
CHUNK_SIZE × Worst-Case-Elementzeitmuss mit ausreichendem Puffer intimeoutSecondspassen, sonst geht das Ende eines Chunks verloren, wenn der Lauf abgeschnitten wird. - Mache die Abbruchbedingung explizit. Rekursiere nur, solange ein voller Chunk zurückgekommen ist. Eine Kette, die nur bei „keine Ergebnisse“ anhält, läuft für immer weiter, wenn die Quelle unterwegs einmal eine verkürzte Seite zurückgibt.
- Persistiere den Fortschritt, bevor du den nächsten Lauf einreihst, damit ein fehlgeschlagener Link beim letzten abgeschlossenen Chunk und nicht am Anfang neu startet.
- Halte jeden Chunk idempotent. Die erneute Verarbeitung eines Chunks nach einem Retry darf nicht zu doppelten Schreibvorgängen führen — führe Schlüsselschreibvorgänge auf dem Datensatz oder der externen ID aus, die du verarbeitest.
- Bevorzuge eine verkettete Chunk-Verarbeitung gegenüber einem riesigen Fan-out, wenn die Arbeit auf einen rate-limitierten Drittanbieter trifft: Eine Kette mit
delayMstaktet sich selbst, wohingegen Tausende auf einmal eingereihte Jobs sofort zur Ausführung anstehen.