diff --git a/apps/api/src/application/operations/delete-instance-operation.ts b/apps/api/src/application/operations/delete-instance-operation.ts index b04fcfe..ec3c2ed 100644 --- a/apps/api/src/application/operations/delete-instance-operation.ts +++ b/apps/api/src/application/operations/delete-instance-operation.ts @@ -328,14 +328,6 @@ export class DeleteInstanceOperation { } try { await this.instances.delete(input.instanceId, input.revision, { allowJobHistory: true }); - this.#emit({ - kind: 'instance', - id: this.id(), - occurredAt: this.clock().toISOString(), - requestId: input.requestId, - instanceId: input.instanceId, - }); - this.#emitJob(ids.job, input.requestId); const finished = this.clock().toISOString(); this.db.transaction(() => { this.db @@ -356,6 +348,16 @@ export class DeleteInstanceOperation { ) .run(finished, finished, ids.job); })(); + // Events only after the terminal rows are committed, so a subscriber that + // refetches on the notification sees the finished job, not 'running'. + this.#emit({ + kind: 'instance', + id: this.id(), + occurredAt: this.clock().toISOString(), + requestId: input.requestId, + instanceId: input.instanceId, + }); + this.#emitJob(ids.job, input.requestId); } catch (error) { const finished = this.clock().toISOString(); const state = error instanceof InstanceServiceError ? 'failed' : 'unknown-result'; @@ -375,6 +377,7 @@ export class DeleteInstanceOperation { .prepare('UPDATE jobs SET status=?,finished_at=?,updated_at=? WHERE id=?') .run(state, finished, finished, ids.job); })(); + this.#emitJob(ids.job, input.requestId); } return this.job(ids.job); } @@ -449,9 +452,10 @@ export class DeleteInstanceOperation { const finished = this.clock().toISOString(); return this.db.transaction(() => { const jobs = this.db - .prepare("SELECT id FROM jobs WHERE operation_id=? AND status='running'") - .all(OPERATION_ID) as Array<{ id: string }>; - for (const { id } of jobs) { + .prepare("SELECT id, request_id FROM jobs WHERE operation_id=? AND status='running'") + .all(OPERATION_ID) as Array<{ id: string; request_id: string }>; + for (const { id, request_id: requestId } of jobs) { + this.#emitJob(id, requestId); this.db .prepare( "UPDATE job_items SET status='unknown-result',result_code='INTERRUPTED',finished_at=?,updated_at=? WHERE job_id=? AND status='running'",