Repository navigation
🤖 feat: watch unclaimed ready CoderWorkspacePoolMember workspaces for use, agent loss, and dormancy - #343
Conversation
…line and check the start build initiator Change-Id: I431d9dab372a21a885caef16659f5e9782a2fad3 Signed-off-by: Thomas Kosiewski <tk@coder.com>
…ne at bind Change-Id: I5b3d8d99f493c268d3b692baed5be0bec89e39a6 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I17d4226fdbc86196ea985c14a760c32b1917fa73 Signed-off-by: Thomas Kosiewski <tk@coder.com>
…se, agent loss, and dormancy Change-Id: I5ffdeabd7e32c5a6236ea4e6f25a7db99d536db3 Signed-off-by: Thomas Kosiewski <tk@coder.com>
…es out Change-Id: I92de215625e1d4d7d6d86d29040b457b2e6997cf Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I7571e9c29a9e2093098ec6b3279e1230663091ba Signed-off-by: Thomas Kosiewski <tk@coder.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@codex security review |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d35c750507
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. Swish! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…ember-watch Change-Id: I143a402026f82a331eb21147af3cee4ce0fbeca0 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
|
@codex security review |
|
Codex Review: Didn't find any major issues. What shall we delve into next? Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
Summary
This PR adds the watch rules of an unclaimed ready
CoderWorkspacePoolMember(plan 6.2 step 10) to the dormant reconciler. Nothing registers the reconciler yet, so no user sees a change.Every 60 s, one read of the workspace runs these rules in plan order:
last_used_atlater thanreadyLastUsedAtsetsUsed=True: someone used the workspace without a claim. A used member is never failed, never extended, and not read again. The pool releases it (PR 10), and the cleanup in PR 8c keeps its workspace. A template-wide write is not use: when the new value is within 5 s of the template'supdated_at, or another unclaimed member of the pool already moved its baseline to the same value, the member moves its baseline and stays unused.Ready=FalsewithAgentNotReady, and the phase staysReady. After 5 minutes the member fails withAgentLost.dormant_atordeleting_atis set: the member fails withDormant.Refs #153
Background
This is PR 8b of the
CoderWorkspacePoolstack (#153). It stacks on PR 8a (#339). PR 8c (cleanup) stacks on this PR.The watch of a bound member (plan 6.2 step 11 rule 3: a deleted workspace makes the claim
Lost) moves to PR 11 (claims), because it only matters with claims. The plan's PR 11 row records this.Implementation
readOwnPoolMemberWorkspaceis split intoreadPoolMemberWorkspace(the read and the identity check: owner,kwp-name, template) andpoolMemberStartBuildStep(start build ID, initiator, transition, version). No behavior change for readiness and extensions. The split lets rule 1 run between the two, so a used member that someone also stopped isUsed, notFailed.watchReady(new filecoderworkspacepoolmember_watch.go) runs the rules.keepWarmnow takes the workspace thatwatchReadyread, instead of reading it again.checkPoolMemberUsecompares whole seconds, because status stores whole seconds. Both times come from Coder's clock. The template guard readsGET /templates/{id}only whenlast_used_atmoved, and lists the pool's members (labelcoder.com/workspace-pool-uid) only when the template time does not match.poolMemberAgentStepruns the readiness rules on the start build again. The 5 minutes count from theReadycondition'slastTransitionTimewith reasonAgentNotReady.Limit: a failed read between two
AgentNotReadyreads setsReady=TruewithCoderUnavailableagain (as before this PR), so the 5 minutes restart. The member then fails later, not never.Validation
New tests (
coderworkspacepoolmember_watch_test.go):TestPoolMemberWatchesUse(plan mutation 9): a claimed prebuild (last_used_ataftercreated_at, set before ready) is not use. Use after ready setsUsed=True. An external stop then does not fail the member, it gets no extension at its deadline, it is not requeued, and later reconciles read nothing from Coder.TestPoolMemberTemplateWideWrite(plan mutation 10): a template schedule update is not use for either member, also after the template'supdated_atmoved again (the second member matches the first member's baseline). Real use afterward is still use.TestPoolMemberWatchRules: a short agent disconnect only makes the member not ready. A disconnect of 5 minutes, counted from the first read that found it, fails it withAgentLost. Dormancy fails it withDormant.The shared
requireMemberhelper now allowsReady=Falsein phaseReadywith reasonAgentNotReady.Mutation checks: I removed one control at a time, and each removal made a named test fail (13 of 13): plan mutations 9 and 10, the
updated_atwindow, the sibling check, rule 1 itself, the early return of a used member, its missing requeue, the agent rule, its start time, its 5-minute threshold,Ready=False, the dormant rule, and the start build check. A 14th mutation (excluding the member itself from the sibling check) survived, because the member's own baseline is always earlier than the new value. I removed that check.Gates on the final commit: drift (codegen, manifests, installer, API reference: no diff),
make docs-check, dormant-CRD guard, docs lint and spelling,make verify-vendor,make build,make lint, actionlint,make test,make test-integration,make vuln, race. All passed.Size
346 hand-written lines (about 220 production, 126 test, counting removals). No generated files.
Risks
None for users. The reconciler is dormant: nothing registers it.
Generated with
mux• Model:anthropic:claude-opus-5-5• Thinking:high• Cost:$121.59