diff --git a/apps/sim/app/api/schedules/execute/route.test.ts b/apps/sim/app/api/schedules/execute/route.test.ts index 2fe434e87b2..2d0fa95ff55 100644 --- a/apps/sim/app/api/schedules/execute/route.test.ts +++ b/apps/sim/app/api/schedules/execute/route.test.ts @@ -50,6 +50,15 @@ vi.mock('@/background/schedule-execution', () => ({ executeScheduleJob: mockExecuteScheduleJob, executeJobInline: mockExecuteJobInline, releaseScheduleLock: mockReleaseScheduleLock, + buildScheduleFailureUpdate: (now: Date, nextRunAt: Date | null) => ({ + updatedAt: now, + lastQueuedAt: null, + nextRunAt, + failedCount: { type: 'sql' }, + lastFailedAt: now, + status: { type: 'sql' }, + infraRetryCount: 0, + }), })) vi.mock('@/lib/core/config/feature-flags', () => mockFeatureFlags) diff --git a/apps/sim/app/api/schedules/execute/route.ts b/apps/sim/app/api/schedules/execute/route.ts index 6dedd8d7494..414ae81047b 100644 --- a/apps/sim/app/api/schedules/execute/route.ts +++ b/apps/sim/app/api/schedules/execute/route.ts @@ -27,12 +27,12 @@ import { SCHEDULE_WORKFLOW_ENQUEUE_LIMIT, } from '@/lib/workflows/schedules/execution-limits' import { + buildScheduleFailureUpdate, executeJobInline, executeScheduleJob, releaseScheduleLock, type ScheduleExecutionPayload, } from '@/background/schedule-execution' -import { MAX_CONSECUTIVE_FAILURES } from '@/triggers/constants' export const dynamic = 'force-dynamic' export const maxDuration = 3600 @@ -321,15 +321,7 @@ async function markClaimedScheduleFailed( const now = new Date() await db .update(workflowSchedule) - .set({ - updatedAt: now, - lastQueuedAt: null, - lastFailedAt: now, - nextRunAt: getScheduleNextRunAt(schedule, now), - failedCount: sql`COALESCE(${workflowSchedule.failedCount}, 0) + 1`, - status: sql`CASE WHEN COALESCE(${workflowSchedule.failedCount}, 0) + 1 >= ${MAX_CONSECUTIVE_FAILURES} THEN 'disabled' ELSE 'active' END`, - infraRetryCount: 0, - }) + .set(buildScheduleFailureUpdate(now, getScheduleNextRunAt(schedule, now))) .where( and( eq(workflowSchedule.id, schedule.id), @@ -482,15 +474,7 @@ async function recoverStaleDatabaseScheduleJobs(now: Date): Promise { await tx .update(workflowSchedule) - .set({ - updatedAt: now, - lastQueuedAt: null, - lastFailedAt: now, - nextRunAt: getScheduleNextRunAt(payload, now), - failedCount: sql`COALESCE(${workflowSchedule.failedCount}, 0) + 1`, - status: sql`CASE WHEN COALESCE(${workflowSchedule.failedCount}, 0) + 1 >= ${MAX_CONSECUTIVE_FAILURES} THEN 'disabled' ELSE 'active' END`, - infraRetryCount: 0, - }) + .set(buildScheduleFailureUpdate(now, getScheduleNextRunAt(payload, now))) .where( and( eq(workflowSchedule.id, payload.scheduleId), diff --git a/apps/sim/background/schedule-execution.ts b/apps/sim/background/schedule-execution.ts index 4c240e5f1e7..b90886d7f71 100644 --- a/apps/sim/background/schedule-execution.ts +++ b/apps/sim/background/schedule-execution.ts @@ -76,6 +76,29 @@ function resetScheduleInfraRetryCount(): Pick