Skip to content

Conversation

@adityachoudhari26
Copy link
Contributor

@adityachoudhari26 adityachoudhari26 commented Nov 3, 2025

Summary by CodeRabbit

  • New Features

    • Per-target policy caching and materialized views for faster policy reads.
    • Public trigger to recompute per-target policy views after changes.
  • Behavioral Changes

    • Policy create/update now proceed without surfacing backend upsert errors (errors are no longer propagated).
  • Performance

    • Fewer repeated policy computations by serving from per-target caches and background recomputation.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Walkthrough

Policy Upsert was changed to not return errors, record changesets, and trigger per-target policy recomputation; ReleaseTargets gained per-target materialized policy caches and a public RecomputeTargetPolicies method. Event handlers and workspace initialization now call Upsert without handling errors; GetPolicies reads from per-target caches and errors if absent.

Changes

Cohort / File(s) Summary
Policy event handler
apps/workspace-engine/pkg/events/handler/policies/policies.go
HandlePolicyCreated and HandlePolicyUpdated now call Upsert(...) without checking or propagating any return value; HandlePolicyDeleted unchanged.
Policy store
apps/workspace-engine/pkg/workspace/store/policy.go
Upsert signature changed to drop returned error; it records changes via changeset.FromContext and p.store.changeset.RecordUpsert(policy), then calls RecomputeTargetPolicies(). Remove now triggers RecomputeTargetPolicies() after deletion and returns an error when policy not found.
Release targets & caching
apps/workspace-engine/pkg/workspace/store/release_targets.go
Added per-target targetPolicies cache and recompute plumbing; introduced RecomputeTargetPolicies() (public) and targetPoliciesRecomputeFunc(...); GetPolicies now reads from per-target cached views and returns an error if the per-target view is missing.
Workspace population
apps/workspace-engine/pkg/workspace/populate_workspace.go
Initial-state population now calls ws.Policies().Upsert(ctx, policy) without handling or returning errors (signature adjusted to match new Upsert).
Tests / benchmarks
apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
Benchmark setup updated to call st.Policies.Upsert(ctx, pol) without error checks; remaining changes are formatting/whitespace.

Sequence Diagram(s)

sequenceDiagram
    participant Handler as Event Handler
    participant Policies as Policies Store
    participant ReleaseTargets as ReleaseTargets
    participant Cache as Per-Target Cache

    rect rgb(220,235,255)
    note right of Handler: Policy create/update (new)
    Handler->>Policies: Upsert(ctx, policy)
    Policies->>Policies: record changeset (changeset.FromContext / RecordUpsert)
    Policies->>ReleaseTargets: RecomputeTargetPolicies()
    ReleaseTargets->>Cache: recompute & populate per-target views
    Cache-->>ReleaseTargets: views ready
    ReleaseTargets-->>Policies: recompute done
    Policies-->>Handler: returns (no error)
    end

    rect rgb(255,235,220)
    note right of Handler: Policy delete (new)
    Handler->>Policies: Remove(ctx, id)
    alt exists
        Policies->>Policies: delete & record changeset
        Policies->>ReleaseTargets: RecomputeTargetPolicies()
        ReleaseTargets->>Cache: update views
        ReleaseTargets-->>Policies: result
        Policies-->>Handler: return nil
    else not found
        Policies-->>Handler: return error (not found)
    end
    end

    rect rgb(235,255,235)
    note right of Consumers: Policy query (new)
    Consumer->>ReleaseTargets: GetPolicies(ctx, target)
    alt cached view exists
        ReleaseTargets->>Cache: read per-target view
        Cache-->>ReleaseTargets: policies
        ReleaseTargets-->>Consumer: policies
    else missing
        ReleaseTargets-->>Consumer: return error (missing view)
    end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to concurrency and lifecycle in apps/workspace-engine/pkg/workspace/store/release_targets.go.
  • Verify callers and call sites now correctly handle the removed error from Upsert, especially in event handlers and initialization.
  • Check tracing/observability and error paths around recomputation for correctness and failure isolation.

Possibly related PRs

  • policy view #682 — modifies workspace policy and release-target computation paths; likely overlaps with per-target policy view recomputation and Policies.Upsert/Remove behavior.

Poem

🐰 I nibble bytes in moonlit rows,
I hop where policy breeze goes.
Caches bloom and targets wake —
I stitch the change for system's sake.
A rabbit cheers: the views remake.

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: caching target policies in a materialized view, which is supported by the addition of per-target policy caching via targetPolicies map and RecomputeTargetPolicies method.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cache-target-policies

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 413f832 and 1619f16.

📒 Files selected for processing (5)
  • apps/workspace-engine/pkg/events/handler/policies/policies.go (2 hunks)
  • apps/workspace-engine/pkg/workspace/populate_workspace.go (1 hunks)
  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go (5 hunks)
  • apps/workspace-engine/pkg/workspace/store/policy.go (3 hunks)
  • apps/workspace-engine/pkg/workspace/store/release_targets.go (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
apps/workspace-engine/**/*.go

📄 CodeRabbit inference engine (apps/workspace-engine/CLAUDE.md)

apps/workspace-engine/**/*.go: Do not add extraneous inline comments that state the obvious
Do not add comments that simply restate what the code does
Do not add comments for standard Go patterns (e.g., noting WaitGroup or semaphore usage)
Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Files:

  • apps/workspace-engine/pkg/events/handler/policies/policies.go
  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
  • apps/workspace-engine/pkg/workspace/store/policy.go
apps/workspace-engine/**/*_test.go

📄 CodeRabbit inference engine (apps/workspace-engine/CLAUDE.md)

Follow the existing test structure used in *_test.go files

Files:

  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
🧠 Learnings (10)
📓 Common learnings
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 637
File: packages/events/src/kafka/client.ts:10-16
Timestamp: 2025-08-01T04:41:41.345Z
Learning: User adityachoudhari26 prefers not to add null safety checks for required environment variables when they are guaranteed to be present in their deployment configuration, similar to their preference for simplicity over defensive programming in test code.
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 601
File: e2e/tests/api/policies/retry-policy.spec.ts:23-24
Timestamp: 2025-06-24T23:52:50.732Z
Learning: The user adityachoudhari26 prefers not to add null safety checks or defensive programming in test code, particularly in e2e tests, as they prioritize simplicity and focus on the main functionality being tested rather than comprehensive error handling within the test itself.
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add comments for standard Go patterns (e.g., noting WaitGroup or semaphore usage)

Applied to files:

  • apps/workspace-engine/pkg/events/handler/policies/policies.go
  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
  • apps/workspace-engine/pkg/workspace/store/policy.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add comments that simply restate what the code does

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add extraneous inline comments that state the obvious

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*_test.go : Follow the existing test structure used in *_test.go files

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Include edge cases in tests (empty values, special characters, unicode) for condition types

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Use table-driven tests for all condition types

Applied to files:

  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
📚 Learning: 2025-08-12T20:49:05.086Z
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 655
File: apps/workspace-engine/pkg/engine/workspace/fluent.go:166-171
Timestamp: 2025-08-12T20:49:05.086Z
Learning: The UpdateDeploymentVersions() method with OperationCreate case in apps/workspace-engine/pkg/engine/workspace/fluent.go is specifically designed only for creating new deployment versions, not for handling potential duplicates or existing versions.

Applied to files:

  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
📚 Learning: 2025-10-07T16:44:54.938Z
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 673
File: apps/workspace-engine/pkg/db/deployment_variables.go:51-65
Timestamp: 2025-10-07T16:44:54.938Z
Learning: In `apps/workspace-engine/pkg/db/deployment_variables.go`, the `default_value_id` field is intentionally scanned from the database but not assigned to the `DefaultValueId` field in the proto struct. This is a temporary decision and the field assignment is deferred for later implementation.

Applied to files:

  • apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go
🧬 Code graph analysis (5)
apps/workspace-engine/pkg/events/handler/policies/policies.go (1)
apps/workspace-engine/pkg/workspace/store/policy.go (1)
  • Policies (18-21)
apps/workspace-engine/pkg/workspace/populate_workspace.go (1)
apps/workspace-engine/pkg/workspace/store/policy.go (1)
  • Policies (18-21)
apps/workspace-engine/pkg/workspace/store/release_targets.go (4)
apps/workspace-engine/pkg/workspace/store/store.go (2)
  • New (10-34)
  • Store (36-58)
apps/workspace-engine/pkg/workspace/store/materialized/view.go (4)
  • New (34-48)
  • MaterializedView (19-27)
  • IsAlreadyStarted (65-67)
  • RecomputeFunc (10-10)
apps/workspace-engine/pkg/oapi/oapi.gen.go (2)
  • Policy (342-355)
  • ReleaseTarget (445-449)
apps/workspace-engine/pkg/cmap/concurrent_map.go (1)
  • ConcurrentMap (23-26)
apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go (2)
apps/workspace-engine/pkg/selector/langs/cel/cel.go (1)
  • CelSelector (55-58)
apps/workspace-engine/pkg/oapi/oapi.gen.go (2)
  • Value (566-568)
  • LiteralValue (326-328)
apps/workspace-engine/pkg/workspace/store/policy.go (2)
apps/workspace-engine/pkg/oapi/oapi.gen.go (1)
  • Policy (342-355)
apps/workspace-engine/pkg/workspace/store/release_targets.go (1)
  • ReleaseTargets (29-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Format
  • GitHub Check: Lint
  • GitHub Check: Typecheck
  • GitHub Check: workspace-engine-tests
  • GitHub Check: tests
🔇 Additional comments (7)
apps/workspace-engine/pkg/events/handler/policies/policies.go (1)

22-22: LGTM: Upsert calls correctly updated for new signature.

The removal of error handling aligns with the updated Upsert signature in apps/workspace-engine/pkg/workspace/store/policy.go (line 39), which no longer returns an error. The handlers correctly proceed to return nil after the upsert operation.

Also applies to: 37-37

apps/workspace-engine/pkg/workspace/populate_workspace.go (1)

46-46: LGTM: Upsert call updated for new signature.

The change correctly reflects the updated Policies.Upsert signature that no longer returns an error, as modified in apps/workspace-engine/pkg/workspace/store/policy.go (line 39).

apps/workspace-engine/pkg/workspace/releasemanager/deployment/planner_bench_test.go (2)

236-236: LGTM: Benchmark updated for new Upsert signature.

The change correctly reflects the updated Policies.Upsert signature that no longer returns an error.


204-204: LGTM: Formatting improvements.

The blank lines improve code readability without affecting functionality.

Also applies to: 210-210, 703-703, 709-709, 753-753, 787-787

apps/workspace-engine/pkg/workspace/store/release_targets.go (2)

151-158: LGTM: Recompute function factory correctly implemented.

The function properly captures the target in the closure and delegates to computePolicies.


8-8: LGTM: Target policy cache infrastructure correctly added.

The cmap import and targetPolicies field additions properly support the per-target policy caching mechanism.

Also applies to: 25-25, 32-33

apps/workspace-engine/pkg/workspace/store/policy.go (1)

39-52: Review comment is inaccurate—actual computation is asynchronous, not synchronous cache rebuild.

The RecomputeTargetPolicies() method creates MaterializedView objects synchronously, but each view's materialized.New() call launches computePolicies() asynchronously via go m.runCompute(ctx) (materialized/view.go:86). The synchronous portion—loop iteration, object allocation, and map operations—is lightweight. The expensive cache computation happens in separate goroutines, not blocking the policy mutation.

This pattern is consistent across the codebase (systems.go, environments.go, deployments.go) and reflects the intended design of materialized views: synchronous setup with asynchronous recomputation.

Likely an incorrect or invalid review comment.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

github-actions bot commented Nov 3, 2025

📊 DB Package Test Coverage

pkg/db coverage: 57.0%

View detailed coverage report in artifacts

@github-actions
Copy link

github-actions bot commented Nov 3, 2025

📊 Code Coverage Report

workspace-engine coverage: 46.5%

View detailed coverage report in artifacts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 797cf4e and c63bb4e.

📒 Files selected for processing (3)
  • apps/workspace-engine/pkg/events/handler/policies/policies.go (1 hunks)
  • apps/workspace-engine/pkg/workspace/store/policy.go (3 hunks)
  • apps/workspace-engine/pkg/workspace/store/release_targets.go (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
apps/workspace-engine/**/*.go

📄 CodeRabbit inference engine (apps/workspace-engine/CLAUDE.md)

apps/workspace-engine/**/*.go: Do not add extraneous inline comments that state the obvious
Do not add comments that simply restate what the code does
Do not add comments for standard Go patterns (e.g., noting WaitGroup or semaphore usage)
Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Files:

  • apps/workspace-engine/pkg/events/handler/policies/policies.go
  • apps/workspace-engine/pkg/workspace/store/policy.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
🧠 Learnings (7)
📓 Common learnings
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 637
File: packages/events/src/kafka/client.ts:10-16
Timestamp: 2025-08-01T04:41:41.345Z
Learning: User adityachoudhari26 prefers not to add null safety checks for required environment variables when they are guaranteed to be present in their deployment configuration, similar to their preference for simplicity over defensive programming in test code.
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 601
File: e2e/tests/api/policies/retry-policy.spec.ts:23-24
Timestamp: 2025-06-24T23:52:50.732Z
Learning: The user adityachoudhari26 prefers not to add null safety checks or defensive programming in test code, particularly in e2e tests, as they prioritize simplicity and focus on the main functionality being tested rather than comprehensive error handling within the test itself.
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/policy.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*_test.go : Follow the existing test structure used in *_test.go files

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/policy.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/mapping/protobuf_mappings.go : Add mapping functions for the new condition in pkg/mapping/protobuf_mappings.go

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/policy.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add comments for standard Go patterns (e.g., noting WaitGroup or semaphore usage)

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add extraneous inline comments that state the obvious

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Include edge cases in tests (empty values, special characters, unicode) for condition types

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
🧬 Code graph analysis (3)
apps/workspace-engine/pkg/events/handler/policies/policies.go (1)
apps/workspace-engine/pkg/workspace/store/policy.go (1)
  • Policies (19-22)
apps/workspace-engine/pkg/workspace/store/policy.go (1)
apps/workspace-engine/pkg/workspace/store/release_targets.go (1)
  • ReleaseTargets (29-34)
apps/workspace-engine/pkg/workspace/store/release_targets.go (5)
apps/workspace-engine/pkg/workspace/store/repository/repo.go (1)
  • New (17-39)
apps/workspace-engine/pkg/workspace/store/store.go (2)
  • New (10-34)
  • Store (36-58)
apps/workspace-engine/pkg/workspace/store/materialized/view.go (4)
  • New (34-48)
  • MaterializedView (19-27)
  • IsAlreadyStarted (65-67)
  • RecomputeFunc (10-10)
apps/workspace-engine/pkg/oapi/oapi.gen.go (2)
  • Policy (342-355)
  • ReleaseTarget (445-449)
apps/workspace-engine/pkg/cmap/concurrent_map.go (1)
  • ConcurrentMap (23-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Typecheck
  • GitHub Check: Format
  • GitHub Check: Lint
  • GitHub Check: tests
  • GitHub Check: workspace-engine-tests

Comment on lines 145 to 153
allTargets := r.targets.Get()
for targetKey, target := range allTargets {
t := target
key := targetKey
mv := materialized.New(r.targetPoliciesRecomputeFunc(t))
r.targetPolicies.Set(key, mv)
}

return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove stale cache entries for deleted targets.

Line 145: RecomputeTargetPolicies rebuilds entries for current targets but never drops keys that disappeared from allTargets. When release targets are deleted, their per-target caches linger indefinitely, leaking memory and leaving stale views accessible through GetPolicies. Please remove any keys absent from the recomputed target set (for example by clearing the map before repopulating or explicitly calling r.targetPolicies.Remove for those keys) before returning.

🤖 Prompt for AI Agents
In apps/workspace-engine/pkg/workspace/store/release_targets.go around lines 145
to 153, RecomputeTargetPolicies currently repopulates r.targetPolicies for keys
present in allTargets but never removes entries for keys that were deleted,
leaking cached materializations; modify the function to first remove stale keys
(either by clearing r.targetPolicies entirely before the loop or by iterating
existing r.targetPolicies keys and calling r.targetPolicies.Remove for any key
not present in allTargets) and then repopulate r.targetPolicies with
materialized entries for the current targets so deleted targets no longer retain
cached state.

@github-actions
Copy link

github-actions bot commented Nov 3, 2025

📊 DB Package Test Coverage

pkg/db coverage: 57.0%

View detailed coverage report in artifacts

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
apps/workspace-engine/pkg/workspace/store/release_targets.go (2)

141-149: Stale target policy caches linger after target removal

Reiterating earlier feedback: RecomputeTargetPolicies only rebuilds entries for keys present in allTargets, but it never clears entries for keys that disappeared. Release targets that have been deleted keep their cached policies indefinitely, leaking memory and exposing stale data through GetPolicies. Please drop keys absent from allTargets (by clearing before repopulating, or removing the missing keys as you iterate) before you finish recomputation.


209-214: Restore lazy initialization for per-target caches

This still regresses callers: if GetPolicies runs before RecomputeTargetPolicies seeds r.targetPolicies—for example in a workspace with no policy mutations yet—we now error with “target policies not found…”, whereas previously we computed on demand. Please reinstate lazy creation on cache miss (or eagerly seed during construction) so that GetPolicies continues to work from a cold start.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c63bb4e and 413f832.

📒 Files selected for processing (4)
  • apps/workspace-engine/pkg/events/handler/policies/policies.go (2 hunks)
  • apps/workspace-engine/pkg/workspace/populate_workspace.go (1 hunks)
  • apps/workspace-engine/pkg/workspace/store/policy.go (3 hunks)
  • apps/workspace-engine/pkg/workspace/store/release_targets.go (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
apps/workspace-engine/**/*.go

📄 CodeRabbit inference engine (apps/workspace-engine/CLAUDE.md)

apps/workspace-engine/**/*.go: Do not add extraneous inline comments that state the obvious
Do not add comments that simply restate what the code does
Do not add comments for standard Go patterns (e.g., noting WaitGroup or semaphore usage)
Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/events/handler/policies/policies.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
  • apps/workspace-engine/pkg/workspace/store/policy.go
🧠 Learnings (8)
📓 Common learnings
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 637
File: packages/events/src/kafka/client.ts:10-16
Timestamp: 2025-08-01T04:41:41.345Z
Learning: User adityachoudhari26 prefers not to add null safety checks for required environment variables when they are guaranteed to be present in their deployment configuration, similar to their preference for simplicity over defensive programming in test code.
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 601
File: e2e/tests/api/policies/retry-policy.spec.ts:23-24
Timestamp: 2025-06-24T23:52:50.732Z
Learning: The user adityachoudhari26 prefers not to add null safety checks or defensive programming in test code, particularly in e2e tests, as they prioritize simplicity and focus on the main functionality being tested rather than comprehensive error handling within the test itself.
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Write comments that explain why, document complex logic/algorithms, provide non-obvious context, include TODO/FIXME, and document exported functions/types/methods

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add comments that simply restate what the code does

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add comments for standard Go patterns (e.g., noting WaitGroup or semaphore usage)

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T20:49:05.086Z
Learnt from: adityachoudhari26
Repo: ctrlplanedev/ctrlplane PR: 655
File: apps/workspace-engine/pkg/engine/workspace/fluent.go:166-171
Timestamp: 2025-08-12T20:49:05.086Z
Learning: The UpdateDeploymentVersions() method with OperationCreate case in apps/workspace-engine/pkg/engine/workspace/fluent.go is specifically designed only for creating new deployment versions, not for handling potential duplicates or existing versions.

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*.go : Do not add extraneous inline comments that state the obvious

Applied to files:

  • apps/workspace-engine/pkg/workspace/populate_workspace.go
  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/**/*_test.go : Follow the existing test structure used in *_test.go files

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
📚 Learning: 2025-08-12T18:13:54.630Z
Learnt from: CR
Repo: ctrlplanedev/ctrlplane PR: 0
File: apps/workspace-engine/CLAUDE.md:0-0
Timestamp: 2025-08-12T18:13:54.630Z
Learning: Applies to apps/workspace-engine/pkg/model/selector/**/*_test.go : Include edge cases in tests (empty values, special characters, unicode) for condition types

Applied to files:

  • apps/workspace-engine/pkg/workspace/store/release_targets.go
🧬 Code graph analysis (3)
apps/workspace-engine/pkg/events/handler/policies/policies.go (1)
apps/workspace-engine/pkg/workspace/store/policy.go (1)
  • Policies (18-21)
apps/workspace-engine/pkg/workspace/store/release_targets.go (4)
apps/workspace-engine/pkg/workspace/store/store.go (2)
  • New (10-34)
  • Store (36-58)
apps/workspace-engine/pkg/workspace/store/materialized/view.go (4)
  • New (34-48)
  • MaterializedView (19-27)
  • IsAlreadyStarted (65-67)
  • RecomputeFunc (10-10)
apps/workspace-engine/pkg/oapi/oapi.gen.go (2)
  • Policy (342-355)
  • ReleaseTarget (445-449)
apps/workspace-engine/pkg/cmap/concurrent_map.go (1)
  • ConcurrentMap (23-26)
apps/workspace-engine/pkg/workspace/store/policy.go (2)
apps/workspace-engine/pkg/oapi/oapi.gen.go (1)
  • Policy (342-355)
apps/workspace-engine/pkg/workspace/store/release_targets.go (1)
  • ReleaseTargets (29-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Typecheck
  • GitHub Check: Lint
  • GitHub Check: workspace-engine-tests
  • GitHub Check: tests
🔇 Additional comments (3)
apps/workspace-engine/pkg/events/handler/policies/policies.go (1)

22-24: Upsert call aligns with new signature

Confirming the event handler now matches the void-returning Policies.Upsert; no further handling is required here.

apps/workspace-engine/pkg/workspace/populate_workspace.go (1)

45-47: Populate path updated correctly

The workspace bootstrap now reflects the signature change by dropping error handling around Policies().Upsert, keeping initialization coherent.

apps/workspace-engine/pkg/workspace/store/policy.go (1)

39-52: Policy mutations now fan out recomputation

Persisting the policy, normalizing metadata, and then triggering RecomputeTargetPolicies keeps the cache in sync with policy writes.

Comment on lines 61 to +69
func (r *ReleaseTargets) Recompute(ctx context.Context) error {
return r.targets.StartRecompute(ctx)
if err := r.targets.StartRecompute(ctx); err != nil && !materialized.IsAlreadyStarted(err) {
return err
}
r.RecomputeTargetPolicies()
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Wait for target recompute before rebuilding caches

Recompute fires a recompute of r.targets and then immediately pulls r.targets.Get(). Because StartRecompute is asynchronous, the subsequent cache rebuild can run against the old target map, so new targets never receive a policy view unless another recompute happens later. Please block on the recompute finishing (e.g., WaitIfRunning) before calling RecomputeTargetPolicies, and surface any resulting error.

🤖 Prompt for AI Agents
In apps/workspace-engine/pkg/workspace/store/release_targets.go around lines 64
to 69, the Recompute function starts an asynchronous recompute and then
immediately rebuilds target policies, which can race with StartRecompute and use
an old target map; change the flow to wait for the recompute to finish (use the
provided materialized.WaitIfRunning or equivalent on r.targets) after
StartRecompute returns and before calling RecomputeTargetPolicies, and if
WaitIfRunning (or the wait call) returns an error, return that error instead of
proceeding so the caller sees recompute failures.

@github-actions
Copy link

github-actions bot commented Nov 3, 2025

📊 DB Package Test Coverage

pkg/db coverage: 57.0%

View detailed coverage report in artifacts

@github-actions
Copy link

github-actions bot commented Nov 3, 2025

📊 Code Coverage Report

workspace-engine coverage: 46.5%

View detailed coverage report in artifacts

@adityachoudhari26 adityachoudhari26 merged commit e4ba529 into main Nov 3, 2025
8 checks passed
@adityachoudhari26 adityachoudhari26 deleted the cache-target-policies branch November 3, 2025 20:01
This was referenced Nov 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants