Skip to content

Commit c903ba1

Browse files
fix(api): project pending resume attempts
1 parent a4c1152 commit c903ba1

2 files changed

Lines changed: 41 additions & 7 deletions

File tree

apps/sim/lib/workflows/executor/execution-status.test.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ describe('getWorkflowExecutionStatus queue projection', () => {
5757
})
5858

5959
it('uses the resume entry ID when the queued work is a resume attempt', async () => {
60-
queueTableRows(schemaMock.resumeQueue, [{ id: 'resume-entry-1' }])
60+
queueTableRows(schemaMock.resumeQueue, [{ id: 'resume-entry-1', status: 'claimed' }])
6161
mockGetJob.mockResolvedValueOnce({
6262
status: 'processing',
6363
createdAt: new Date('2026-08-05T12:00:00.000Z'),
@@ -84,7 +84,7 @@ describe('getWorkflowExecutionStatus queue projection', () => {
8484
status: 'paused',
8585
},
8686
])
87-
queueTableRows(schemaMock.resumeQueue, [{ id: 'resume-entry-1' }])
87+
queueTableRows(schemaMock.resumeQueue, [{ id: 'resume-entry-1', status: 'claimed' }])
8888
mockGetJob.mockResolvedValueOnce({
8989
status: 'pending',
9090
createdAt: new Date('2026-08-05T12:00:00.000Z'),
@@ -112,6 +112,7 @@ describe('getWorkflowExecutionStatus queue projection', () => {
112112
queueTableRows(schemaMock.resumeQueue, [
113113
{
114114
id: 'resume-entry-1',
115+
status: 'claimed',
115116
queuedAt: new Date('2026-08-05T12:00:00.000Z'),
116117
claimedAt: new Date('2026-08-05T12:00:01.000Z'),
117118
},
@@ -129,6 +130,35 @@ describe('getWorkflowExecutionStatus queue projection', () => {
129130
})
130131
})
131132

133+
it('projects a pending serialized resume as queued', async () => {
134+
queueTableRows(schemaMock.workflowExecutionLogs, [
135+
{
136+
executionId: 'execution-1',
137+
workflowId: 'workflow-1',
138+
status: 'paused',
139+
trigger: 'api',
140+
},
141+
])
142+
queueTableRows(schemaMock.resumeQueue, [
143+
{
144+
id: 'resume-entry-2',
145+
status: 'pending',
146+
queuedAt: new Date('2026-08-05T12:00:02.000Z'),
147+
claimedAt: null,
148+
},
149+
])
150+
151+
const status = await getWorkflowExecutionStatus(input)
152+
153+
expect(status).toMatchObject({
154+
executionId: 'execution-1',
155+
status: 'queued',
156+
startedAt: '2026-08-05T12:00:02.000Z',
157+
paused: null,
158+
})
159+
expect(mockGetJob).not.toHaveBeenCalled()
160+
})
161+
132162
it('returns completed queue output when requested', async () => {
133163
mockGetJob.mockResolvedValueOnce({
134164
status: 'completed',

apps/sim/lib/workflows/executor/execution-status.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { db } from '@sim/db'
22
import { pausedExecutions, resumeQueue, workflowExecutionLogs } from '@sim/db/schema'
3-
import { and, eq } from 'drizzle-orm'
3+
import { and, eq, inArray, sql } from 'drizzle-orm'
44
import type { WorkflowExecutionStatusResponse } from '@/lib/api/contracts/workflows'
55
import { getJobQueue } from '@/lib/core/async-jobs'
66
import type { Job } from '@/lib/core/async-jobs/types'
@@ -157,6 +157,7 @@ export async function getWorkflowExecutionStatus(
157157
const [activeResume] = await db
158158
.select({
159159
id: resumeQueue.id,
160+
status: resumeQueue.status,
160161
queuedAt: resumeQueue.queuedAt,
161162
claimedAt: resumeQueue.claimedAt,
162163
})
@@ -165,13 +166,16 @@ export async function getWorkflowExecutionStatus(
165166
and(
166167
eq(resumeQueue.parentExecutionId, executionId),
167168
eq(resumeQueue.newExecutionId, executionId),
168-
eq(resumeQueue.status, 'claimed')
169+
inArray(resumeQueue.status, ['pending', 'claimed'] as const)
169170
)
170171
)
172+
.orderBy(sql`case when ${resumeQueue.status} = 'claimed' then 0 else 1 end`)
171173
.limit(1)
172174

173175
const queueJobIds = [
174-
...(activeResume ? [`${RESUME_EXECUTION_JOB_ID_PREFIX}${activeResume.id}`] : []),
176+
...(activeResume?.status === 'claimed'
177+
? [`${RESUME_EXECUTION_JOB_ID_PREFIX}${activeResume.id}`]
178+
: []),
175179
...(!logRow ? [`${WORKFLOW_EXECUTION_JOB_ID_PREFIX}${executionId}`] : []),
176180
]
177181

@@ -184,13 +188,13 @@ export async function getWorkflowExecutionStatus(
184188
}
185189
}
186190

187-
if (activeResume && logRow) {
191+
if (activeResume) {
188192
const startedAt = activeResume.claimedAt ?? activeResume.queuedAt
189193
return {
190194
executionId,
191195
workflowId,
192196
status: 'queued',
193-
trigger: logRow.trigger,
197+
trigger: logRow?.trigger ?? 'api',
194198
level: 'info',
195199
startedAt: startedAt.toISOString(),
196200
endedAt: null,

0 commit comments

Comments
 (0)