fix(worker): claim workspace lock in main before enqueue (D-02)
The lock was previously claimed when the worker reported `running`, which is after `agent.prompt` had already started streaming. Two concurrent runs targeting the same workspace could both pass the main-side checks, both get enqueued, and both read half-written state before one of them lost the lock race and was cancelled mid-flight. Move the `claimWorkspaceLock` call into `dispatchRunToWorker` so main coordinates exclusivity authoritatively. If the lock is unavailable, the run is finished as failed and never enqueued. The worker-side lease-renewal path is preserved since it is a lease, not a lock.
This commit is contained in:
1 parent
f86b3ddbac
commit
ff0c01fe87
2 files changed
+27
-4
No files matched your search
@@ -110,12 +110,11 @@ export async function handleWorkerMessage(
|
||||
});
|
||||
}
|
||||
if (event.status === "running") {
|
||||
// D-02: Workspace lock is claimed authoritatively in main's
|
||||
// dispatchRunToWorker before enqueue. Only lease renewal and
|
||||
// run-started housekeeping run here.
|
||||
try {
|
||||
const run = db.getRun(event.runId);
|
||||
if (run.workspaceId && !db.claimWorkspaceLock(run.workspaceId, run.id)) {
|
||||
logger.error(`[workspace] Failed to claim lock for workspace ${run.workspaceId} when run ${run.id} entered running state. Cancelling run.`);
|
||||
worker?.postMessage({ type: "cancel-run", runId: run.id });
|
||||
}
|
||||
db.renewTaskLease(run.taskId, run.id);
|
||||
onRunStarted?.(run.id, run.taskId, run.agentId, run.companyId);
|
||||
} catch {
|
||||
|
||||
Reference in new issue
Block a user