Prezentare generală
O rulare a unei funcții de logică este limitată detimeoutSeconds (maximum 900 de secunde). Orice lucru care nu poate fi finalizat în acel interval — o resincronizare completă, un fan-out per înregistrare, un API de la o terță parte care aplică limitare de rată — trebuie împărțit în execuții mai mici.
enqueueJobs face exact asta: le cere lucrătorilor Twenty să ruleze mai târziu una dintre funcțiile de logică ale aplicației tale, o dată pentru fiecare payload, fiecare rulare în propriul său proces, cu propriul său buget de timeout. Apelantul returnează imediat.
Pune rulările în coadă
ImportăenqueueJobs din twenty-sdk/logic-function, indică-l către universalIdentifier al funcției logice de rulat și transmite câte un payload pentru fiecare rulare funcției enqueue.
src/logic-functions/sync-all-contacts.ts
Logic function not found și nu se pune nimic în coadă. Un singur apel acceptă până la 200 joburi.
enqueueJobs revine imediat ce joburile sunt acceptate, nu când au fost rulate. Nu întoarce rezultatele țintelor — fă ca fiecare țintă să scrie ce produce în magazinul cheie-valoare sau într-o înregistrare din spațiul de lucru dacă trebuie să le citești ulterior. Pentru a afla dacă o execuție s-a încheiat, interogați periodic starea jobului.Ajutorul mai vechi
enqueueJob, care pune în coadă un singur job per apel, este depreciat. Folosiți în schimb enqueueJobs cu o listă jobs cu un singur element. Argumentul payloads este și el învechit — transmiteți în schimb jobs, care acceptă aceeași încărcătură utilă pentru fiecare execuție și vă permite să denumiți fiecare execuție.Interogați periodic joburile
enqueueJobs returnează câte un jobId pentru fiecare execuție pusă în coadă, în aceeași ordine ca lucrările pe care le-ai transmis. getJobs citește stadiul la care au ajuns acele execuții, într-un singur apel.
getJobs citește cel mult 200 de ID-uri, aceeași limită pe care enqueueJobs o aplică unui lot.
Fiecare intrare conține ID-ul solicitat:
O lucrare care nu a fost încă preluată apare în mod normal ca
PRIORITIZED, nu ca WAITING, deoarece lucrările aplicației sunt puse în coadă la o prioritate mică fixă. COMPLETED și FAILED sunt stările terminale. O buclă de interogare ar trebui, de asemenea, să renunțe singură după un număr limitat de încercări, în loc să aștepte la nesfârșit, deoarece o execuție poate fi citită doar cât timp coada o păstrează: 4 ore după finalizare, 7 zile după eșec și, în ambele cazuri, doar cele mai recente 1000 de lucrări în acea stare.
getJobs returnează numai lucrările pe care încă le păstrează, astfel încât un ID care a fost eliminat — sau nu a existat niciodată — pur și simplu lipsește din rezultat, în loc să provoace o eroare pentru întregul lot. Compară ceea ce primești înapoi cu ceea ce ai solicitat pentru a le identifica și tratează un ID lipsă ca „nu mai este cunoscut”, ceea ce nu este același răspuns ca „nu a rulat niciodată”.
Stările sunt limitate la spațiul de lucru din care se efectuează apelul, astfel încât un spațiu de lucru nu poate citi niciodată lucrarea altui spațiu de lucru.
Alege propriul ID al lucrării
Transmitejobs în loc de payloads pentru a denumi tu însuți fiecare execuție. ID-ul pe care îl transmiți este cel pe care îl acceptă getJobs, astfel încât un apelant poate interoga o lucrare fără a fi nevoit să stocheze ceea ce a returnat enqueueJobs.
_, . sau -, iar două lucrări dintr-un singur apel nu pot avea același ID. Transmite fie payloads, fie jobs, niciodată ambele. Când omiți jobId, Twenty generează unul.
Un jobId este, de asemenea, o cheie de idempotență: punerea în coadă a unui ID pe care coada îl păstrează încă este acceptată, dar nu pornește o a doua execuție, iar getJobs continuă să raporteze prima execuție. Astfel, reîncercarea punerii în coadă este sigură. Două avertismente: garanția durează numai cât timp lucrarea este păstrată, astfel încât același ID poate porni o execuție nouă după ce cea originală a fost eliminată, iar ID-urile sunt partajate de fiecare aplicație dintr-un spațiu de lucru, așa că adaugă un prefix ID-urilor tale dacă o coliziune ar conta.
Opțiuni job
Opțiunile se aplică fiecărei rulări din lot.Prioritatea nu este încă configurabilă. Joburile puse în coadă rulează întotdeauna cu cea mai joasă prioritate, astfel încât activitatea platformei să nu fie niciodată întârziată de joburile aplicației. Controlul asupra priorității va fi disponibil în curând.
Reîncercați după un eșec temporar
Twenty nu reîncearcă fiecare excepție din codul aplicației. O eroare obișnuită lansată este tratată ca un eșec permanent. Pentru un eșec temporar, o funcție logică pusă în coadă poate solicita până la trei reîncercări prin lansareaRetryableLogicFunctionError.
RetryableLogicFunctionError atunci când este posibil. Dacă o extindeți, nu îi înlocuiți name: Twenty recunoaște numele serializat RetryableLogicFunctionError în toate mediile de execuție.
retryCount este 0 pentru execuția inițială și crește doar atunci când codul aplicației solicită o reîncercare. maxRetries este cel mult 3 și poate fi mai mic atunci când sarcina din coadă are o limită totală de reîncercări mai mică. Eșecurile platformei nu cresc retryCount, deși consumă în continuare bugetul general de siguranță al cozii.
Coada întârzie încercările de reîncercare folosind backoff exponențial și jitter. Întârzierea exactă nu este garantată în mod intenționat, astfel că codul aplicației nu ar trebui să depindă de producerea unei reîncercări la un moment precis. După ce se atinge maxRetries, o altă RetryableLogicFunctionError este înregistrată ca eșecul final al aplicației, fără o altă execuție.
Folosește-l: parcurge pe pagini o sincronizare lungă
Forma clasică este o funcție care pune în coadă ea însăși cu următorul cursor. Fiecare rulare procesează o pagină de lucru bine în interiorul propriului timeout, iar lanțul se oprește când nu mai rămâne nimic.src/logic-functions/sync-contacts-page.ts
Dispersare pe înregistrare
Când munca este în mod natural pe element, pune în coadă un job per element într-un singur apel și lasă workerii să le proceseze în paralel în loc să iterezi inline.Bune practici pentru muncă de lungă durată
Două reguli acoperă aproape orice job lung: folosește recursie în locul buclelor și procesează un segment limitat per rulare. O rulare care încearcă să facă totul este modul de eșec — atinge timeout-ul, iar la o reîncercare începe din nou totul de la zero. În schimb, dimensionează un segment astfel încât să se termine confortabil în interiorultimeoutSeconds, persistă-ți poziția și pune în coadă următoarea rulare.
src/logic-functions/enrich-companies-batch.ts
- Dimensionează segmentul pornind de la cel mai lent element, nu de la medie.
CHUNK_SIZE × worst-case item timetrebuie să încapă întimeoutSecondscu marjă, altfel „coada” unui segment se pierde când rularea este întreruptă. - Fă condiția de terminare explicită. Apelează recursiv doar cât timp a revenit un segment complet. Un lanț care se oprește doar pe baza „niciun rezultat” va continua la nesfârșit dacă sursa returnează vreodată o pagină scurtă la mijloc.
- Păstrează progresul înainte de a pune în coadă următoarea rulare, astfel încât o verigă eșuată să repornească de la ultimul segment finalizat în loc de la început.
- Păstrează fiecare segment idempotent. Reprocesarea unui segment după o reîncercare nu trebuie să ducă la scrieri duble — leagă scrierile de înregistrarea sau ID-ul extern pe care îl procesezi.
- Preferă un lanț segmentat în locul unei dispersări uriașe atunci când munca lovește o terță parte cu limită de rată: un lanț cu
delayMsîși dozează singur ritmul, în timp ce mii de joburi puse în coadă deodată devin toate eligibile imediat.