Implement issue execution lock with deferred wake promotion
Add per-issue execution lock (executionRunId, executionAgentNameKey, executionLockedAt) to prevent concurrent runs on the same issue. Same-name wakes are coalesced into the active run; different-name wakes are deferred and promoted when the lock holder finishes. Includes checkout/release run ownership enforcement, agent run ID propagation from JWT claims, wakeup deduplication across assignee and mention wakes, and claimQueuedRun extraction for reuse. Adds two DB migrations for checkoutRunId and execution lock columns. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1063,23 +1063,25 @@ export function agentRoutes(db: Db) {
|
||||
}
|
||||
assertCompanyAccess(req, issue.companyId);
|
||||
|
||||
if (!issue.assigneeAgentId || issue.status !== "in_progress") {
|
||||
res.json(null);
|
||||
return;
|
||||
let run = issue.executionRunId ? await heartbeat.getRun(issue.executionRunId) : null;
|
||||
if (run && run.status !== "queued" && run.status !== "running") {
|
||||
run = null;
|
||||
}
|
||||
|
||||
const agent = await svc.getById(issue.assigneeAgentId);
|
||||
if (!agent) {
|
||||
res.json(null);
|
||||
return;
|
||||
if (!run && issue.assigneeAgentId && issue.status === "in_progress") {
|
||||
run = await heartbeat.getActiveRunForAgent(issue.assigneeAgentId);
|
||||
}
|
||||
|
||||
const run = await heartbeat.getActiveRunForAgent(issue.assigneeAgentId);
|
||||
if (!run) {
|
||||
res.json(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const agent = await svc.getById(run.agentId);
|
||||
if (!agent) {
|
||||
res.json(null);
|
||||
return;
|
||||
}
|
||||
|
||||
res.json({
|
||||
...run,
|
||||
agentId: agent.id,
|
||||
|
||||
Reference in New Issue
Block a user