Skip to content

Commit e56960e

Browse files
fix(tables): count dispatcher pre-stamps in "X running" during active dispatch
The live SSE path counts pending pre-stamps (isExecInFlight) but countRunningCells excluded them, so each per-window refetch reset the badge from ~20 to 0 (visible flicker now that the control stays shown via hasActiveDispatch). Include unclaimed pre-stamps in byRowId when a dispatch is active; keep excluding them only in the no-dispatch fallback (orphan case).
1 parent 3f3efc9 commit e56960e

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

apps/sim/lib/table/dispatcher.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,13 @@ export async function insertDispatch(input: {
197197
*
198198
* Hits the `(table_id, status)` partial index on table_row_executions. */
199199
export async function countRunningCells(
200-
tableId: string
200+
tableId: string,
201+
opts?: { includeUnclaimedPreStamps?: boolean }
201202
): Promise<{ total: number; byRowId: Record<string, number> }> {
203+
// `pending` + null-executionId rows are unclaimed pre-stamps. With an active
204+
// dispatch they're real queued work (include); with none they're abandoned
205+
// orphans that would pin the badge above zero forever (exclude).
206+
const excludeOrphanPreStamps = !opts?.includeUnclaimedPreStamps
202207
const rows = await db
203208
.select({
204209
rowId: tableRowExecutions.rowId,
@@ -209,9 +214,9 @@ export async function countRunningCells(
209214
and(
210215
eq(tableRowExecutions.tableId, tableId),
211216
inArray(tableRowExecutions.status, ['queued', 'running', 'pending']),
212-
// Exclude orphan pre-stamps (`pending` + null executionId). De Morgan of
213-
// NOT(pending AND null) — `status` is NOT NULL so `ne` is well-defined.
214-
or(ne(tableRowExecutions.status, 'pending'), isNotNull(tableRowExecutions.executionId))
217+
excludeOrphanPreStamps
218+
? or(ne(tableRowExecutions.status, 'pending'), isNotNull(tableRowExecutions.executionId))
219+
: undefined
215220
)
216221
)
217222
.groupBy(tableRowExecutions.rowId)
@@ -261,9 +266,10 @@ export async function countActiveRunCells(
261266
return rowsAhead * groupCount
262267
}
263268

264-
// One round-trip per dispatch + the sidecar count, all in parallel.
269+
// Include pre-stamps so `byRowId` matches the live SSE count (which counts
270+
// `pending`); otherwise the badge flickers 20→0 on each refetch.
265271
const [sidecar, perDispatch] = await Promise.all([
266-
countRunningCells(tableId),
272+
countRunningCells(tableId, { includeUnclaimedPreStamps: true }),
267273
Promise.all(active.map(countRowsAhead)),
268274
])
269275
const total = perDispatch.reduce((sum, n) => sum + n, 0)

0 commit comments

Comments
 (0)