Skip to content

Commit c37821d

Browse files
sweetmantechclaude
andcommitted
fix(sandbox): KISS lifecycle claim — combiner under lib/sessions, IfMatch via updateSession
Two review fixes: 1) Move `claimSessionLifecycleRunId.ts` from `lib/supabase/sessions/` to `lib/sessions/`. The combiner doesn't directly query Supabase — it composes two underlying helpers, so per api convention it belongs alongside other domain composers, not under the Supabase namespace. 2) KISS: delete `claimSessionLifecycleRunIdIfMatch.ts` and use the existing `updateSession` helper for the lease-refresh path. The refresh writes the same `lifecycle_run_id` value back, so an unconditional `updateSession({ lifecycle_run_id: runId })` does the work — accepts a small race where a concurrent stale-reclaim could be overwritten, but the kick path (which DOES use the atomic `claimSessionLifecycleRunIdIfNull`) remains the primary concurrency guard. Two callers (runKick, computeLifecycleWakeDecision) updated to import from the new path. No behavior change at the workflow level. Tests: 2579 / 2579 still pass. lint + tsc clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 22095c2 commit c37821d

5 files changed

Lines changed: 34 additions & 56 deletions

File tree

‎app/workflows/computeLifecycleWakeDecision.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import{getLifecycleDueAtMs}from"@/lib/sandbox/getLifecycleDueAtMs";
22
import{hasRuntimeSandboxState}from"@/lib/sandbox/hasRuntimeSandboxState";
3-
import{claimSessionLifecycleRunId}from"@/lib/supabase/sessions/claimSessionLifecycleRunId";
3+
import{claimSessionLifecycleRunId}from"@/lib/sessions/claimSessionLifecycleRunId";
44
import{selectSessions}from"@/lib/supabase/sessions/selectSessions";
55

66
interfaceLifecycleWakeDecision{

‎lib/sandbox/runKick.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createLifecycleRunId } from "@/lib/sandbox/createLifecycleRunId";
44
import{isLifecycleRunStale}from"@/lib/sandbox/isLifecycleRunStale";
55
import{reclaimStaleLease}from"@/lib/sandbox/reclaimStaleLease";
66
import{shouldStartLifecycle}from"@/lib/sandbox/shouldStartLifecycle";
7-
import{claimSessionLifecycleRunId}from"@/lib/supabase/sessions/claimSessionLifecycleRunId";
7+
import{claimSessionLifecycleRunId}from"@/lib/sessions/claimSessionLifecycleRunId";
88
import{selectSessions}from"@/lib/supabase/sessions/selectSessions";
99
import{updateSession}from"@/lib/supabase/sessions/updateSession";
1010
importtype{SandboxLifecycleReason}from"@/lib/sandbox/sandboxLifecycleTypes";
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import{claimSessionLifecycleRunIdIfNull}from"@/lib/supabase/sessions/claimSessionLifecycleRunIdIfNull";
2+
import{updateSession}from"@/lib/supabase/sessions/updateSession";
3+
4+
/**
5+
* Combiner for the two `lifecycle_run_id` claim operations. Lives in
6+
* `lib/sessions/` (not `lib/supabase/sessions/`) because it does not
7+
* directly query Supabase — it composes two underlying helpers.
8+
*
9+
* - `expected = null` (initial claim): atomic `claimSessionLifecycleRunIdIfNull`
10+
* that fails when the row already has a lease.
11+
* - `expected = runId` (workflow refresh): plain `updateSession` write that
12+
* re-asserts the current lease without a conditional WHERE. Accepts a
13+
* small race where a stale-reclaim could be overwritten — the kick path
14+
* (which DOES use the atomic IfNull check) remains the primary
15+
* concurrency guard.
16+
*
17+
* @param sessionId - The session id to claim against.
18+
* @param runId - The new lease value to write.
19+
* @param expected - The expected current value; defaults to null.
20+
* @returns true on success, false when an initial claim was already taken.
21+
*/
22+
exportasyncfunctionclaimSessionLifecycleRunId(
23+
sessionId: string,
24+
runId: string,
25+
expected: string|null=null,
26+
): Promise<boolean>{
27+
if(expected===null){
28+
returnclaimSessionLifecycleRunIdIfNull(sessionId,runId);
29+
}
30+
constupdated=awaitupdateSession(sessionId,{lifecycle_run_id: runId});
31+
returnupdated!==null;
32+
}

‎lib/supabase/sessions/claimSessionLifecycleRunId.ts‎

Lines changed: 0 additions & 23 deletions
This file was deleted.

‎lib/supabase/sessions/claimSessionLifecycleRunIdIfMatch.ts‎

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)