Files
AgentCompany/src/main/database
ZacharyZhang-NY 8f7054630b fix(heartbeat): atomic find-or-create + checkout to eliminate duplicate task race
Replace the racy three-step heartbeat path (listAgentTasks ->
findReusableHeartbeatTask -> saveTask -> checkoutTask) with a single
transactional acquireHeartbeatTask method. The prior flow allowed two
concurrent scheduler ticks to both observe "no reusable heartbeat" and
both INSERT a fresh [Heartbeat] task before either CAS-checked out,
producing duplicates that cleanupDuplicateHeartbeatTasks had to mop up.

acquireHeartbeatTask runs inside BEGIN IMMEDIATE so concurrent ticks
serialize on the writer lock. Inside the transaction it first attempts
to claim any existing claimable [Heartbeat] task (todo/backlog/done/
in_review with checkout_run_id IS NULL), reviving done/in_review by
resetting status. If nothing is claimable but an in-flight heartbeat
exists (status NOT IN done/cancelled), it returns null instead of
creating a duplicate. Only when no heartbeat task exists at all does it
INSERT a new one, already in 'in_progress' with checkout_run_id set.

cleanupDuplicateHeartbeatTasks remains as deletion-side defense.
2026-04-16 22:19:42 -04:00
..
2026-04-04 12:03:50 -04:00
2026-04-05 20:14:48 -04:00
2026-04-04 12:03:50 -04:00
2026-04-04 12:03:50 -04:00
2026-04-05 20:14:48 -04:00
2026-04-04 12:03:50 -04:00
2026-04-16 14:48:51 -04:00
2026-04-04 12:03:50 -04:00
2026-04-04 12:03:50 -04:00
2026-04-07 20:18:47 -04:00
2026-04-05 20:14:48 -04:00
2026-04-05 20:14:48 -04:00
2026-04-16 14:48:51 -04:00
2026-04-04 12:03:50 -04:00
2026-04-04 12:03:50 -04:00
2026-04-04 12:03:50 -04:00
2026-04-04 12:03:50 -04:00
2026-04-07 20:18:47 -04:00
2026-04-05 20:14:48 -04:00
2026-04-05 20:14:48 -04:00
2026-04-04 12:03:50 -04:00
2026-04-04 12:03:50 -04:00
2026-04-05 20:14:48 -04:00
2026-04-05 20:14:48 -04:00
2026-04-04 12:03:50 -04:00