Skip to content

Commit 158fe3d

Browse files
fix(table): cut dispatcher cold-start by lazy-loading heavy import chains
The trigger.dev table-run-dispatcher spent ~6s in module init before its first batchTriggerAndWait — it imports lib/table/service for getTableById, which eagerly imported lib/table/trigger → @/lib/webhooks/processor → webhook-execution + executor, dragging the entire workflow-execution stack into the dispatcher container even though it never fires a trigger. - trigger.ts lazy-imports the webhook processor + polling utils inside fireTableTrigger (the only consumer), so importing service no longer pulls the executor. - buildEnqueueItems only imports the cell job (for the inline `runner`) on the database backend; the trigger.dev backend triggers by task id and ignores runner.
1 parent f0311a6 commit 158fe3d

2 files changed

Lines changed: 19 additions & 5 deletions

File tree

apps/sim/lib/table/trigger.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
import { createLogger } from '@sim/logger'
1010
import { generateShortId } from '@sim/utils/id'
1111
import type { RowData, TableRow, TableSchema } from '@/lib/table/types'
12-
import { fetchActiveWebhooks } from '@/lib/webhooks/polling/utils'
13-
import { processPolledWebhookEvent } from '@/lib/webhooks/processor'
1412

1513
const logger = createLogger('TableTrigger')
1614

@@ -57,6 +55,11 @@ export async function fireTableTrigger(
5755
requestId: string
5856
): Promise<void> {
5957
try {
58+
// Lazy-imported: `@/lib/webhooks/processor` transitively pulls in the
59+
// workflow executor + blocks stack. Importing it eagerly would force every
60+
// consumer of `lib/table/service` (e.g. the dispatcher, which only needs
61+
// `getTableById`) to pay that cold-start even when no trigger ever fires.
62+
const { fetchActiveWebhooks } = await import('@/lib/webhooks/polling/utils')
6063
const webhooks = await fetchActiveWebhooks('table')
6164
if (webhooks.length === 0) return
6265

@@ -74,6 +77,8 @@ export async function fireTableTrigger(
7477

7578
if (matching.length === 0) return
7679

80+
const { processPolledWebhookEvent } = await import('@/lib/webhooks/processor')
81+
7782
logger.info(
7883
`[${requestId}] Firing ${matching.length} trigger(s) for ${rows.length} ${eventType} event(s) in table ${tableId}`
7984
)

apps/sim/lib/table/workflow-columns.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,20 @@ export function buildPendingRuns(
203203
/** Build the per-cell `{payload, options}` items for `queue.batchEnqueue` /
204204
* `queue.batchEnqueueAndWait`. Hydrates trigger.dev tags, concurrency keys,
205205
* the inline runner, and the cancel key the inline backend uses to map a
206-
* Stop click to the in-flight cell's AbortController. */
206+
* Stop click to the in-flight cell's AbortController.
207+
*
208+
* The `runner` is only consumed by the database (inline) backend — the
209+
* trigger.dev backend triggers by task id. Importing the cell job pulls in
210+
* the entire executor + blocks stack, so on trigger.dev we skip the import
211+
* entirely: the dispatcher container would otherwise pay a multi-second
212+
* cold-start loading code it never runs (the cell runs in its own container). */
207213
export async function buildEnqueueItems(
208214
pendingRuns: WorkflowGroupCellPayload[]
209215
): Promise<Array<{ payload: WorkflowGroupCellPayload; options: EnqueueOptions }>> {
210-
const { executeWorkflowGroupCellJob } = await import('@/background/workflow-column-execution')
216+
const runner = isTriggerDevEnabled
217+
? undefined
218+
: ((await import('@/background/workflow-column-execution'))
219+
.executeWorkflowGroupCellJob as EnqueueOptions['runner'])
211220
return pendingRuns.map((runOpts) => ({
212221
payload: runOpts,
213222
options: {
@@ -225,7 +234,7 @@ export async function buildEnqueueItems(
225234
concurrencyKey: runOpts.tableId,
226235
concurrencyLimit: TABLE_CONCURRENCY_LIMIT,
227236
tags: cellTagsFor(runOpts),
228-
runner: executeWorkflowGroupCellJob as EnqueueOptions['runner'],
237+
...(runner ? { runner } : {}),
229238
cancelKey: cellCancelKey(runOpts.tableId, runOpts.rowId, runOpts.groupId),
230239
},
231240
}))

0 commit comments

Comments
 (0)