timeoutSeconds (900 segundos como máximo). Cualquier cosa que no pueda terminar en esa ventana — una resincronización completa, una distribución por registro, una API de terceros que impone límites de tasa — debe dividirse en ejecuciones más pequeñas.
enqueueJobs hace exactamente eso: solicita a los workers de Twenty que ejecuten más tarde una de las funciones lógicas de tu aplicación, una vez por carga útil, cada ejecución en su propio proceso con su propio presupuesto de tiempo de espera. La llamada devuelve de inmediato.
Poner en cola ejecuciones
ImportaenqueueJobs desde twenty-sdk/logic-function, apúntalo al universalIdentifier de la función lógica que se ejecutará y pasa una carga útil por ejecución para poner en cola.
src/logic-functions/sync-all-contacts.ts
Logic function not found y no se pone nada en cola. Una sola llamada acepta hasta 200 cargas útiles.
enqueueJobs devuelve tan pronto como se aceptan los trabajos, no cuando se han ejecutado. No devuelve los resultados de los destinos: haz que cada destino escriba lo que produce en el almacenamiento de pares clave-valor o en un registro del espacio de trabajo si necesitas leerlo después.El auxiliar
enqueueJob más antiguo, que pone en cola un único trabajo por llamada, ha quedado obsoleto. Usa enqueueJobs con una lista payloads de un elemento en su lugar.Opciones del trabajo
Las opciones se aplican a todas las ejecuciones del lote.La prioridad todavía no es configurable. Los trabajos encolados siempre se ejecutan con la prioridad más baja, para que el trabajo de la plataforma nunca se retrase por detrás de los trabajos de las aplicaciones. El control sobre la prioridad llegará pronto.
Reintentar un fallo transitorio
Twenty no vuelve a intentar todas las excepciones del código de la aplicación. Un error ordinario lanzado se trata como un fallo permanente. Para un fallo transitorio, una función lógica en cola puede solicitar hasta tres reintentos lanzandoRetryableLogicFunctionError.
RetryableLogicFunctionError directamente cuando sea posible. Si lo extiendes, no sustituyas su name: Twenty reconoce el nombre serializado RetryableLogicFunctionError en todos los entornos de ejecución.
retryCount es 0 para la ejecución inicial y aumenta solo cuando el código de la aplicación solicita un reintento. maxRetries es como máximo 3 y puede ser menor cuando el trabajo en cola tiene un límite general de reintentos más bajo. Los fallos de la plataforma no aumentan retryCount, aunque siguen consumiendo el presupuesto general de seguridad de la cola.
La cola retrasa los intentos de reintento con una espera exponencial y fluctuación. El retraso exacto no se garantiza intencionadamente, por lo que el código de la aplicación no debe depender de que un reintento ocurra en un momento preciso. Una vez que se alcanza maxRetries, otro RetryableLogicFunctionError se registra como el fallo final de la aplicación sin otra ejecución.
Úsalo: recorre por páginas una sincronización larga
La forma clásica es una función que se pone en cola a sí misma con el cursor siguiente. Cada ejecución hace una página de trabajo bien dentro de su propio tiempo de espera, y la cadena se detiene cuando no queda nada.src/logic-functions/sync-contacts-page.ts
Dividir por registro
Cuando el trabajo es de forma natural por elemento, pon en cola un trabajo por elemento en una sola llamada y deja que los workers los procesen en paralelo en lugar de iterar en línea.Buenas prácticas para trabajos de larga duración
Dos reglas cubren casi cualquier trabajo largo: usa recursión en lugar de bucles y procesa un bloque acotado por ejecución. Una ejecución que intenta hacerlo todo es la forma en que falla: alcanza el tiempo de espera y, con un reintento, vuelve a empezar todo desde cero. En su lugar, dimensiona un bloque para que termine con holgura dentro detimeoutSeconds, guarda tu posición y pon en cola la siguiente ejecución.
src/logic-functions/enrich-companies-batch.ts
- Dimensiona el bloque a partir del elemento más lento, no del promedio.
CHUNK_SIZE × worst-case item timetiene que caber entimeoutSecondscon margen de sobra, o la parte final de un bloque se pierde cuando se corta la ejecución. - Haz que la condición de terminación sea explícita. Haz recursión solo mientras haya vuelto un bloque completo. Una cadena que se detiene solo con “sin resultados” seguirá ejecutándose para siempre si la fuente alguna vez devuelve una página corta a mitad de camino.
- Guarda el progreso antes de poner en cola la siguiente ejecución, de modo que un eslabón fallido se reinicie desde el último bloque completado en lugar de desde el principio.
- Mantén cada bloque idempotente. Volver a procesar un bloque después de un reintento no debe escribir dos veces — indexa las escrituras por el registro o el id externo que estés procesando.
- Prefiere una cadena por bloques en lugar de una expansión masiva cuando el trabajo interactúa con un tercero con limitación de tasa: una cadena con
delayMsse autorregula, mientras que miles de trabajos encolados a la vez se vuelven elegibles de inmediato.