@@ -5,6 +5,7 @@ import { task } from '@trigger.dev/sdk'
55import { sql } from 'drizzle-orm'
66import { asOrchestrationError } from '@/lib/core/orchestration/types'
77import { getColumnId } from '@/lib/table/column-keys'
8+ import { getDeleteSnapshotBatchSize } from '@/lib/table/constants'
89import { signalTableRowsChanged } from '@/lib/table/events'
910import { assertRowDelete , TableLockedError } from '@/lib/table/mutation-locks'
1011import type { DbTransaction } from '@/lib/table/planner'
@@ -17,7 +18,6 @@ import type { RowData, TableSchema } from '@/lib/table/types'
1718const logger = createLogger ( 'CleanupTableRowTtl' )
1819const cleanupDb = dbFor ( 'cleanup' )
1920
20- const TTL_CLEANUP_BATCH_SIZE = 500
2121const TTL_CLEANUP_MAX_BATCHES = 100
2222
2323interface ExpiredTtlTableRef {
@@ -96,12 +96,12 @@ async function listExpiredTtlTables(nowEpochSeconds: number): Promise<ExpiredTtl
9696 return Array . isArray ( rows ) ? rows : [ ]
9797}
9898
99- function parseDeletedBatch ( rows : unknown ) : DeletedTtlRows {
99+ function parseDeletedBatch ( rows : unknown , batchSize : number ) : DeletedTtlRows {
100100 if ( ! Array . isArray ( rows ) ) {
101101 throw new Error ( 'Table row TTL cleanup did not return deleted rows' )
102102 }
103103 const deletedRows = rows as Array < { id ?: unknown ; data ?: unknown ; createdAt ?: unknown } >
104- if ( deletedRows . length > TTL_CLEANUP_BATCH_SIZE ) {
104+ if ( deletedRows . length > batchSize ) {
105105 throw new Error ( 'Table row TTL cleanup returned an invalid deleted count' )
106106 }
107107 const parsed = deletedRows . map ( ( row ) => {
@@ -129,6 +129,7 @@ async function deleteExpiredTableRowBatch(
129129 workspaceId : string ,
130130 columnKey : string ,
131131 nowEpochSeconds : number ,
132+ batchSize : number ,
132133 after ?: TtlCleanupCursor
133134) : Promise < DeletedTtlRows > {
134135 const rows = await trx . execute < { id : string ; data : RowData ; createdAt : string } > ( sql `
@@ -145,7 +146,7 @@ async function deleteExpiredTableRowBatch(
145146 AND jsonb_typeof(table_row.data->${ columnKey } ) = 'number'
146147 AND (table_row.data->>${ columnKey } )::numeric <= ${ nowEpochSeconds }
147148 ORDER BY table_row.created_at, table_row.id
148- LIMIT ${ TTL_CLEANUP_BATCH_SIZE }
149+ LIMIT ${ batchSize }
149150 FOR UPDATE OF table_row SKIP LOCKED
150151 ), deleted AS (
151152 DELETE FROM ${ userTableRows } AS table_row
@@ -160,12 +161,13 @@ async function deleteExpiredTableRowBatch(
160161 FROM deleted
161162 ORDER BY "createdAt", id
162163 ` )
163- return parseDeletedBatch ( rows )
164+ return parseDeletedBatch ( rows , batchSize )
164165}
165166
166167async function deleteExpiredRowsForTable (
167168 ref : ExpiredTtlTableRef ,
168169 nowEpochSeconds : number ,
170+ batchSize : number ,
169171 after ?: TtlCleanupCursor
170172) : Promise < DeletedTtlBatch > {
171173 try {
@@ -190,6 +192,7 @@ async function deleteExpiredRowsForTable(
190192 table . workspaceId ,
191193 getColumnId ( ttlColumn ) ,
192194 nowEpochSeconds ,
195+ batchSize ,
193196 after
194197 )
195198 return {
@@ -202,7 +205,7 @@ async function deleteExpiredRowsForTable(
202205 { expectedWorkspaceId : ref . workspaceId }
203206 )
204207 if ( batch . attempted && batch . rows . length > 0 ) {
205- void fireTableTrigger (
208+ await fireTableTrigger (
206209 ref . id ,
207210 batch . tableName ,
208211 'delete' ,
@@ -232,6 +235,7 @@ export async function runCleanupTableRowTtl(
232235 }
233236
234237 const nowEpochSeconds = Math . floor ( Date . now ( ) / 1000 )
238+ const batchSize = getDeleteSnapshotBatchSize ( )
235239 const tableRefs = await listExpiredTtlTables ( nowEpochSeconds )
236240 const tableStates : TtlTableCleanupState [ ] = tableRefs . map ( ( ref ) => ( {
237241 ref,
@@ -250,7 +254,12 @@ export async function runCleanupTableRowTtl(
250254 if ( state . complete ) continue
251255 if ( batches === TTL_CLEANUP_MAX_BATCHES || signal ?. aborted ) break
252256
253- const batch = await deleteExpiredRowsForTable ( state . ref , nowEpochSeconds , state . after )
257+ const batch = await deleteExpiredRowsForTable (
258+ state . ref ,
259+ nowEpochSeconds ,
260+ batchSize ,
261+ state . after
262+ )
254263 if ( ! batch . attempted ) {
255264 state . complete = true
256265 continue
@@ -260,7 +269,7 @@ export async function runCleanupTableRowTtl(
260269 deleted += batch . deleted
261270 state . deleted += batch . deleted
262271 state . after = batch . cursor ?? undefined
263- if ( batch . deleted < TTL_CLEANUP_BATCH_SIZE ) state . complete = true
272+ if ( batch . deleted < batchSize ) state . complete = true
264273 }
265274 }
266275
0 commit comments