Repository navigation
fix(operator): support Dynamo 1.5 SGLang embedding canaries - #15159
xianlubird wants to merge 7 commits into
Conversation
Signed-off-by: xianlubird <xianlubird@gmail.com>
|
/ok to test 8a59e88 |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: ai-dynamo/dynamo/.coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review. WalkthroughSGLang container configuration now injects a health-check payload for version 1.5.0 embedding workers when no payload exists. Tests cover default injection, user overrides, chat workers, and newer runtime versions. ChangesSGLang health-check compatibility
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This change provides the required embedding health-check payload for Dynamo 1.5.0 SGLang embedding workers while preserving overrides and leaving other workers unchanged. No merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Warning Some tools did not complete. Review the errors below. 🔧 golangci-lint (2.13.2)Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions Comment ✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
|
Signed-off-by: xianlubird <xianlubird@gmail.com>
|
/ok to test 450811c |
There was a problem hiding this comment.
Questions for the author:
- deploy/operator/internal/dynamo/backend_sglang.go:
DYN_SGL_EMBEDDING_WORKERcan be supplied through KubernetesvalueFrom(for example, a ConfigMap or Secret), but the new resolver deliberately treats that as disabled and does not inject the compatibility payload. Please provide evidence that this configuration path is unsupported for 1.5 embedding workers, or a way to preserve the shim when the runtime resolves it to true.
Signed-off-by: xianlubird <xianlubird@gmail.com>
|
/ok to test 585b027 |
There was a problem hiding this comment.
Previously reported defects still present:
- Original discussion: Still present:
sglangEmbeddingWorkerEnabledonly treats literalDYN_SGL_EMBEDDING_WORKERvalues as enabling embedding mode, so a supportedvalueFromsource that resolves true at runtime still receives no compatibility health-check payload. - Original discussion: Still present:
sglangEmbeddingWorkerEnabledtreatsDYN_SGL_EMBEDDING_WORKERsupplied throughvalueFromorenvFromas disabled. A 1.5.0 embedding worker enabled by a ConfigMap or Secret therefore misses the compatibility payload and retains the failing chat-shaped canary. - Original discussion: The previously reported valueFrom/envFrom embedding-worker configuration defect remains present:
sglangEmbeddingWorkerEnabledtreats a valueFrom-backedDYN_SGL_EMBEDDING_WORKERas disabled, and EnvFrom is not represented incontainer.Env. A 1.5.0 worker that resolves this supported setting to true still misses the compatibility payload and retains the failing canary. - Original discussion: Verified still present:
DYN_SGL_EMBEDDING_WORKERcan be supplied via a supported KubernetesvalueFromorenvFromsource, but the resolver treats both as disabled. A 1.5.0 embedding worker resolving this setting to true therefore receives no compatibility payload and its active canary continues to fail.
Signed-off-by: xianlubird <xianlubird@gmail.com>
|
/ok to test f9ff95e |
Signed-off-by: xianlubird <xianlubird@gmail.com>
|
/ok to test 55940de |
|
A few concerns here. For a 1.5.0 SGLang embedding worker with The fix adds ~100 lines of flag parsing to the operator to handle something that isn't broken — walking If users want active canary probing on a 1.5.0 embedding worker, the right path is a one-line addition to the upgrade guide: set |
There was a problem hiding this comment.
Previously reported defects still present:
- Original discussion: Still present: Grove materializes component envFrom before generatePodSpecForComponent applies graph-level spec.env. The temporary envFrom value wins MergeEnvs, then Restore removes it and also loses a conflicting graph-level explicit DYN_HEALTH_CHECK_PAYLOAD; the lower-precedence envFrom value takes effect instead.
- Original discussion: Still present: Grove materializes component envFrom before generatePodSpecForComponent merges graph-level spec.env. A materialized component DYN_HEALTH_CHECK_PAYLOAD wins MergeEnvs, then Restore removes that name entirely, dropping a conflicting graph-level explicit payload and allowing the lower-precedence envFrom value to take effect.
- Original discussion: Still present: Grove materializes component envFrom before generatePodSpecForComponent merges graph-level spec.env. The materialized entry wins that merge, and Restore then removes the matching name from the final pod, dropping a conflicting graph-level explicit DYN_HEALTH_CHECK_PAYLOAD override.
- Original discussion: Still present: the compatibility payload decision is persisted from a point-in-time ConfigMap/Secret lookup, while neither DCD nor DGD reconciliation watches referenced envFrom objects. Later adding or removing DYN_HEALTH_CHECK_PAYLOAD can therefore leave newly created pods with a stale explicit override or without the required default.
- Original discussion: Still present: the rendered explicit compatibility payload is based on a point-in-time envFrom read, but neither the DCD controller nor the Grove path watches referenced ConfigMaps or Secrets. Later source changes can leave the explicit default shadowing a newly supplied payload, or leave pods without a default after a sourced payload is removed.
- Original discussion: Still present: the rendered explicit compatibility payload is based on the envFrom source contents at reconciliation time, but neither the DGD nor DCD controller watches referenced ConfigMaps or Secrets. Adding or removing DYN_HEALTH_CHECK_PAYLOAD later leaves the existing pod template with a stale explicit override or without a needed default for subsequently created pods.
|
@tmonty12 One important detail: the 1.5.0 embedding worker passes a generation-shaped It therefore registers a canary target; it does not take the payload-less transport-readiness fallback. An explicit If they keep their default DGD and upgrade to a version that enables active checks, embedding workers could remain unready and disrupt traffic. The mixed-version compatibility documentation does not state this configuration requirement. I think the default upgrade path needs a fix. WDYT the direction ? |
There was a problem hiding this comment.
Previously reported defects still present:
- Original discussion: Still present: Grove materializes component envFrom before
generatePodSpecForComponentmerges graph-levelspec.env; a materialized component payload wins that merge, thenRestoreremoves the name entirely, dropping a conflicting graph-level explicit payload. - Original discussion: Still present: Grove materializes component envFrom before generatePodSpecForComponent merges graph-level spec.env. A materialized component DYN_HEALTH_CHECK_PAYLOAD wins MergeEnvs, then Restore removes that name from the final pod, dropping a conflicting graph-level explicit payload and allowing the lower-precedence envFrom value to take effect.
- Original discussion: Still present: Grove materializes component envFrom before graph-level spec.env is merged. The materialized component value wins MergeEnvs, then Restore removes that name, dropping a conflicting graph-level explicit DYN_HEALTH_CHECK_PAYLOAD override and allowing the lower-precedence envFrom value to take effect.
- Original discussion: Still present: compatibility injection is based on a point-in-time envFrom ConfigMap/Secret read, but the DCD and DGD reconciliation paths do not watch those referenced objects. Later adding or removing DYN_HEALTH_CHECK_PAYLOAD can leave newly created pods using a stale explicit payload or lacking the needed compatibility default.
- Original discussion: Still present: compatibility payload injection is based on a point-in-time ConfigMap/Secret lookup, but neither the DCD nor DGD reconciliation path watches referenced envFrom objects. Later source changes can leave rendered pod templates with a stale explicit override or without the required default.
- Original discussion: Still present: in the Grove path, component envFrom is materialized before graph-level spec.env is merged by generatePodSpecForComponent. A materialized component DYN_HEALTH_CHECK_PAYLOAD can win the merge and then be removed by Restore, dropping a conflicting graph-level explicit payload and allowing the lower-precedence envFrom source to take effect.
- Original discussion: Still present: the Grove path materializes component envFrom before generatePodSpecForComponent applies graph-level spec.env. The materialized value wins MergeEnvs, then Restore removes that name, dropping a conflicting graph-level explicit DYN_HEALTH_CHECK_PAYLOAD and leaving the lower-precedence envFrom value effective.
- Original discussion: Still present: the compatibility payload decision is persisted from a point-in-time ConfigMap or Secret lookup, but neither the DCD nor DGD controller watches referenced envFrom objects. Later adding or removing DYN_HEALTH_CHECK_PAYLOAD can leave newly created pods with a stale explicit override or without the required default.
- Original discussion: Still present: the compatibility payload decision is persisted from a point-in-time ConfigMap/Secret lookup, while neither rendering path watches referenced envFrom objects. Later source changes can leave new pods with a stale explicit override or without the required default.
- Original discussion: Still present: the compatibility payload decision is persisted from a point-in-time envFrom ConfigMap/Secret lookup, while the rendered workload is not tied to later changes in those referenced objects. Adding or removing DYN_HEALTH_CHECK_PAYLOAD after reconciliation can leave new pods with a stale explicit override or without the needed default.
- Original discussion: Still present: the override rows in TestSGLangBackend_Dynamo15EmbeddingHealthCheckPayload only inspect findEnvVar, which returns the first DYN_HEALTH_CHECK_PAYLOAD entry. A regression that appends a generated payload after the user-provided literal or valueFrom override would still pass; the override cases need to assert there is exactly one payload entry and that it is the configured override.
- Original discussion: Still present: the override tests still inspect only the first matching payload with
findEnvVar, so an appended generated payload after a user-provided entry would not be detected.
|
Thanks for the clarification — you're right, I looked at the v1.5.0 That said, A simpler approach: in The |
Signed-off-by: xianlubird <xianlubird@gmail.com>
|
/ok to test bb869b2 |
|
@tmonty12 I simplified the shim to read only literal I kept one guard for |
Signed-off-by: xianlubird <xianlubird@gmail.com>
|
/ok to test d0a446d |
There was a problem hiding this comment.
Previously reported defects still present:
- Original discussion: Still present:
sglangEmbeddingWorkerEnabledignoresDYN_SGL_EMBEDDING_WORKERwhen it is supplied throughvalueFrom, so a 1.5.0 pod whose referenced value enables embedding mode still receives no compatibility health-check payload. - Original discussion: Still present:
sglangEnvFromMaySettreats any unprefixedenvFromsource as possibly definingDYN_HEALTH_CHECK_PAYLOAD, so an unrelated ConfigMap or Secret suppresses the required 1.5.0 embedding-worker default payload.
Summary
DYN_HEALTH_CHECK_PAYLOADoverrides and leave chat workers and newer runtimes unchanged.Where should the reviewer start?
Start in
deploy/operator/internal/dynamo/backend_sglang.go, where the compatibility payload is gated by the resolved runtime version and--embedding-workermode. The adjacent table test covers the affected path and each scope boundary.Related Issues
Validation
go test ./internal/dynamo -run "^TestSGLangBackend_"Summary by CodeRabbit