Skip to content

Rolling updates for versiond-managed binaries (blue/green + drain, part 1 of #1367)#1437

Open
snevolin wants to merge 24 commits into
gonka-ai:ak/pixelplex-refactoring-into-r2from
snevolin:sn/versiond-rolling-updates
Open

Rolling updates for versiond-managed binaries (blue/green + drain, part 1 of #1367)#1437
snevolin wants to merge 24 commits into
gonka-ai:ak/pixelplex-refactoring-into-r2from
snevolin:sn/versiond-rolling-updates

Conversation

@snevolin

Copy link
Copy Markdown

Summary

This PR adds rolling updates for versiond-managed binaries: when governance publishes a
new binary under the same version name (name stays, e.g. v0.2.13, only the sha256
changes), versiond now performs a blue/green swap with drain instead of the current
stop-then-start. In-flight work on the old devshardd child is allowed to finish; the new
child receives traffic only after it is actually ready.

It implements Part 1 (Track A) of the
rolling-update plan
and is the first stage of the HA proposal
#1367
("rolling updates first" per maintainer feedback in the discussion).

Base branch: ak/pixelplex-refactoring-into-r2 (#1366), not main — the feature
builds directly on the HA foundation from that PR (standalone devshardd, shared
Postgres, per-child ports, versiond-router). Intended as a stacked PR.


Motivation

Today a governance sha change is handled by downloadAndSwap as stop-then-start on the
same port
: the old child gets SIGTERM and is SIGKILLed after 5s, before the new binary
has proven it can serve. Any inference longer than ~5s (long SSE /chat/completions,
validation) is cut mid-flight.

For operators this is not cosmetic: a dropped in-flight inference means failed/unanswered
validations (Executor Reputation), and mid-epoch unavailability feeds into cPoC
confirmation ratio. The operator requirement (rolling-update.md §0) is:

  1. requests already accepted by the old instance may finish;
  2. the old instance is stopped only after the new one is ready and reachable;
  3. once the new instance is reachable, new requests go to it while the old one drains.

How a swap works now

poll detects same name, new sha256
        │
        ▼
download into per-sha dir  bin/<name>/<sha>/     ← old child's binary untouched on disk
        │
        ▼
start NEW child on a NEW port                    ← old child keeps serving
        │
        ▼
wait for NEW child readiness (HTTP /ready, not just TCP)
        │
        ▼
atomic route swap: version → NEW port            ← in-flight requests stay on OLD conn
        │
        ▼
old child → "draining" (out of route table, visible in /healthz, no crash-restart)
        │
        ▼
poll /drain/status until inflight == 0  OR  VERSIOND_DRAIN_TIMEOUT
        │
        ▼
SIGTERM (long WaitDelay ≥ DEVSHARD_SHUTDOWN_GRACE) → SIGKILL only as backstop

If the new child never becomes ready, the swap aborts and the old child keeps serving
(retry on the next poll) — a failed rollout no longer takes the version down.


What ships in this PR

versiond (versioned/)

Area Change
Blue/green + drain downloadAndSwap rewritten; per-name current + draining[] children; per-generation port allocation with release; draining children excluded from routes and from the crash-restart loop
Readiness gate waitForReady probes VERSIOND_READY_PATH (default /ready); replaces the TCP-only probe and its "routing anyway" fallback; swap aborts (old keeps serving) on readiness failure
Per-sha installs + GC binaries live in bin/<name>/<sha256>/ (write-once; safe for a draining child's crash-restart); superseded install dirs are GC'd, keeping desired/live/draining plus a small retain cushion; in-progress downloads are never GC'd
Storage guard overlap is enabled only with PGHOST set and no leftover SQLite-owned sessions in the data dir (probed via _meta.db); otherwise versiond falls back to today's stop-then-start — SQLite single-instance setups keep their current behavior
Legacy compatibility binaries released before this work run unchanged: preflight (--print-* flags) falls back to the governance slot name on a recognized "unsupported flag" error (fail-closed on timeouts/signals); /ready falls back to /healthz → TCP for the default path only; missing /drain/status (404/405/501) shortens the drain wait instead of stalling 15m
Oracle input validation version names must be simple path components and unique; sha256 must be 64 hex chars (mirrors chain-side DevshardEscrowParams.Validate); an invalid response fails the poll and leaves running children untouched
Observability /healthz entries now include status (incl. draining), sha256 and binary_version per child — also groundwork for the §1.8 router-evacuation track

devshardd (devshard/cmd/devshardd/)

Endpoint / knob Behavior
GET /ready 200 only after full init and the chain event subscription is active (flips back on disconnect)
POST /drain belt-and-braces: reject new work, finish existing
GET /drain/status {ready, draining, inflight}; inflight counts all non-lifecycle HTTP requests (incl. full SSE stream duration) and is exported as Prometheus gauge devshardd_lifecycle_inflight_requests
DEVSHARD_SHUTDOWN_GRACE replaces the hard-coded 5s server.Shutdown window (default 10m); versiond's kill grace honors it (max(VERSIOND_DRAIN_KILL_GRACE, DEVSHARD_SHUTDOWN_GRACE))

New configuration (all defaulted, no compose changes required)

Env var Default Meaning
VERSIOND_READY_PATH /ready readiness path the supervisor probes
VERSIOND_READY_TIMEOUT 60s max wait for the new child before aborting the swap
VERSIOND_DRAIN_PATH /drain path versiond POSTs to put the old child into drain mode
VERSIOND_DRAIN_STATUS_PATH /drain/status path versiond polls for the old child's in-flight count
VERSIOND_DRAIN_TIMEOUT 15m max wait for the old child to go idle before SIGTERM
VERSIOND_DRAIN_POLL_INTERVAL 1s in-flight poll cadence
VERSIOND_DRAIN_KILL_GRACE 30s wait after SIGTERM before SIGKILL
DEVSHARD_SHUTDOWN_GRACE 10m devshardd graceful-shutdown window on SIGTERM

Test infrastructure

  • Testermint: VersiondTests gains a same-version binary update scenario — a slow
    request keeps running on the old child through the swap, continuity probes assert no
    routing gap, and the draining child is observed to exit. local-test-net's
    testapp-server now builds per-name stamped binaries (-X main.Version=<slot>), as
    required by the protocol-embed check on this base branch.
  • Chain gRPC wiring for devshard flows on fresh builds: testermint now passes
    DEVSHARD_CHAIN_GRPC to devshardctl (its chain_rest is deprecated on this base
    branch), and init-docker-genesis.sh binds the genesis node's gRPC to 0.0.0.0:9090
    (join init already did this) so edge-api/devshardctl can reach it from peer
    containers. Without these, devshard/edge-api testermint flows only pass on stale cached
    images.
  • Go e2e (versioned/e2e): TestSameNameNewSHA_RollingUpdateDrainsOld — long request
    survives a governance sha change while a concurrent request is served by the new binary;
    testapp got /ready, /drain, /drain/status and graceful shutdown to act as a
    drain-aware child.
  • Unit suites extended: swap abort paths (new child not ready → old keeps serving),
    drain idle/timeout branches, GC retention, preflight matrix (stamped / legacy /
    mismatch / timeout), oracle validation, port allocation.

Docs

rolling-update.md
updated to match the implementation: final env defaults, the legacy-compatibility
fallbacks, GC behavior, and the WaitDelay / shutdown-grace interaction.


Compatibility with deployed nodes

Scenario Result
new versiond + already-released devshardd (no --print-*, no /ready) works via legacy fallbacks; first swap away from a legacy child uses the short drain grace (one-time transitional effect)
old versiond + new devshardd works (DEVSHARD_BINARY_LOG_VERSION unset → link-stamp fallback)
SQLite single-instance unchanged behavior (stop-then-start; overlap never enabled)
Postgres-backed nodes full blue/green + drain

No chain changes: versions still come from governance DevshardEscrowParams.ApprovedVersions
via the existing dapi /versions oracle; the wire contract is unchanged.


Test plan

Unit (no Docker)

cd versioned && go test -race ./...        # incl. swap/drain/GC/preflight/oracle suites
cd devshard  && go test -race ./cmd/devshardd/...
make -C devshard ci-testenv-unit

All green (also under -race).

Docker e2e

make -C versioned e2e

All scenarios pass, including TestSameNameNewSHA_RollingUpdateDrainsOld: the in-flight
slow request completes on the old binary, new requests are served by the new one, the
draining child exits cleanly.

Testermint

make local-build build-docker
make run-tests TESTS="VersiondTests"

Note: devshard/edge-api testermint flows require freshly built images plus the chain
gRPC fixes included here (DEVSHARD_CHAIN_GRPC + genesis 0.0.0.0:9090 bind); on stale
cached images the pre-existing gaps are masked.


Out of scope / follow-ups

  • Track B (§1.8): versiond-router host evacuation — upstream down + reload, drain
    poll, operator runbook. The /healthz draining visibility and /drain/status added here
    are the signals that track will consume.
  • Back-pressure cap on concurrently draining children under rapid sha churn.
  • Download size limits (defense-in-depth), exposing per-child inflight through versiond
    /healthz for the §1.8 runbook.

@a-kuprin
a-kuprin force-pushed the ak/pixelplex-refactoring-into-r2 branch 2 times, most recently from 0213646 to ea882d3 Compare July 12, 2026 16:02
@snevolin
snevolin force-pushed the sn/versiond-rolling-updates branch from 071f9c1 to 03129e4 Compare July 13, 2026 03:31

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 03129e4b64

ℹ️ 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".

Comment thread versioned/internal/process/manager.go Outdated
@a-kuprin a-kuprin added this to the v0.2.14-devshard4 milestone Jul 14, 2026
Comment thread devshard/cmd/devshardd/server.go
@a-kuprin

Copy link
Copy Markdown
Collaborator

30s (DrainKillGrace): “we don’t know inflight; don’t stall 15m; give a short cushion then stop asking.”
10m (DEVSHARD_SHUTDOWN_GRACE): “once we have sent SIGTERM, let long requests finish.”

Docs table line that says VERSIOND_DRAIN_KILL_GRACE = “wait after SIGTERM before SIGKILL” is slightly misleading for current code: for devshardd, post-SIGTERM kill grace is really max(DrainKillGrace, DEVSHARD_SHUTDOWN_GRACE), and DrainKillGrace alone is the legacy pre-SIGTERM wait.

DrainKillGrace is used for backward compatibility when versioned is holding old devshardd, that do not have drain support. I think we should align them: let's make DrainKillGrace also 10m, and fix the docs to make it more precise

@a-kuprin

Copy link
Copy Markdown
Collaborator

waitForChild(c, timeout) — used on swap/drain: wait until done or timeout. No outer cancel.
waitForChildContext(ctx, c, timeout) — used only in Manager.Shutdown: wait until done, timeout, or ctx cancelled.

waitForChildContext has 10s timeout, that doesn't match DEVSHARD_SHUTDOWN_GRACE

But as I understand versioned graceful stop or devshardd host stop is deffered for next PR

Comment thread versioned/internal/process/manager.go Outdated
Comment thread versioned/internal/process/manager.go
Comment thread versioned/internal/process/manager.go
@a-kuprin

a-kuprin commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Also at ak/pixelplex-refactoring-into-r2 branch was introduced testenv.
It aims to replace heavy testermint tests.

Consider adding a testenv scenario (e.g. S7), for testing that in-flight session keep living while version swap, node replacement, downing node. It could be used for following cases:

  • Real devshardd lifecycle (/ready, /drain, inflight) under Postgres / multi-versiond
  • Swap while a real chat/SSE or session is in flight
  • mock-dapi can flip /versions sha without a gov proposal

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 62271b9859

ℹ️ 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".

Comment thread devshard/cmd/devshardd/lifecycle.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 714ba4672f

ℹ️ 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".

Comment thread versioned/internal/process/manager.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e056edcb7d

ℹ️ 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".

Comment thread versioned/internal/process/manager.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75690a188a

ℹ️ 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".

Comment thread versioned/internal/process/manager.go Outdated
@snevolin
snevolin force-pushed the sn/versiond-rolling-updates branch from 75690a1 to 1dc1f08 Compare July 16, 2026 13:35

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1dc1f086d6

ℹ️ 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".

Comment thread versioned/internal/process/manager.go
snevolin added 12 commits July 17, 2026 19:48
Install each approved binary by sha256, start replacement children
on a new port, wait for readiness, atomically move routing
to the new child, and drain the old child before stopping it.

Add devshardd lifecycle endpoints, proxy health metadata,
and e2e coverage for same-name sha256 swaps.
Recheck child restart state after backoff so a draining old
child cannot restart after route promotion, and shorten legacy
drain waits when /drain/status is unavailable.

Fail closed on transient preflight probe errors while preserving
legacy unsupported-flag fallback, and validate oracle version
names before reconciling.
Use testify assertions in the new devshard event listener
test, prefer any in the versioned e2e test app JSON maps,
and rename childStart.context to ctx.
Validate oracle-provided sha256 values before reconciliation so invalid
hashes cannot flow into install paths or cleanup. This keeps bad oracle
responses fail-closed while leaving currently running children
unchanged.

Add focused process tests for failed replacement readiness and drain
idle/timeout behavior, and update the e2e hash mismatch case to use a
syntactically valid wrong checksum.

Document the legacy preflight, readiness, and drain fallbacks used during
the first versiond upgrade.
Build version-stamped testapp artifacts for v0.2.11, v0.2.12, and
v0.2.11-rollout so versiond preflight can validate protocol versions in
the full-stack fixture.

Extend VersiondTests with a same-version binary update that keeps a slow
request on the old child, waits for route swap to rollout, checks
continuity probes, and waits for the draining child to exit.
Do not reuse the 10s HTTP shutdown context for child process
teardown.

Give the process manager its own shutdown budget based on the
per-child stop timeout so DEVSHARD_SHUTDOWN_GRACE remains effective
for devshardd children.

Log incomplete HTTP or manager shutdown paths instead of silently
ignoring those errors.
Keep /ready, /drain, and /drain/status off the public
`devshardd` listener and start a private admin listener when
versiond provides DEVSHARD_ADMIN_ADDR.

Probe --print-admin-api-version for devshardd children, allocate a
loopback admin port only for binaries that advertise support, and keep
legacy children on the existing public lifecycle fallback.

Use 127.0.0.1 consistently for child lifecycle probes and strip
inherited DEVSHARD_ADMIN_ADDR before setting per-child env.
Raise VERSIOND_DRAIN_KILL_GRACE to 10m so the first
legacy-to-new devshardd swap gives old in-flight work a real drain
window before SIGTERM.

Keep the default in one exported config constant so Load and manager
normalization stay aligned.

Clarify the overloaded knob semantics in the rolling update design:
legacy no-status cushion, non-devshard child stop timeout, and the
minimum devshardd stop timeout combined with DEVSHARD_SHUTDOWN_GRACE.
Move children for removed approved versions into the draining set
instead of cancelling them synchronously from Reconcile.

This removes the route immediately, disables restart for the old child,
and lets drainAndStop handle the in-flight wait and legacy drain cushion
in the background.

Cover the non-blocking removal path and the legacy no-status grace path
with manager unit tests, and document the removal semantics in the
rolling update design.
Replace the monotonic child port counter with a bounded pool that scans
from BasePort and reuses ports after child exit.

Reserve versiond's own listen port so long-lived supervisors cannot
eventually assign :8080 to a child, and normalize invalid BasePort
values back to the default.

Update manager tests for port reuse, reserved-port skipping, and
out-of-range BasePort handling. Document the bounded child-port pool in
the rolling update design.
Add a devshardd --print-storage-mode capability so versiond can ask
the actual child binary how it resolves DEVSHARD_STORAGE_MODE.

Record the running child's storage mode during preflight and allow
blue/green overlap only when both the running and incoming devshardd
binaries report postgres.

Fall back to stop/start for legacy, hybrid, sqlite, unknown, or failed
probes.

Remove the old versiond-side SQLite probe and its modernc.org/sqlite
dependency. Update rolling-update docs and tests for the new fail-closed
storage-mode gate.
@snevolin
snevolin force-pushed the sn/versiond-rolling-updates branch from 1dc1f08 to 9d84158 Compare July 17, 2026 17:07

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d841580fe

ℹ️ 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".

Comment thread versioned/internal/process/manager.go Outdated
Comment thread versioned/internal/process/manager.go Outdated
Add an S9 citest scenario that updates an approved binary under the
same version name and verifies request continuity, blue/green overlap,
new-request routing, and eventual drain on both versiond hosts.

Cover the hybrid storage fallback separately to prove that unsafe
storage modes use stop/start without overlapping children.

Let Docker assign isolated host ports for concurrent citest stacks and
extend mock-dapi with mutable approved versions and binary serving.
Update the testenv documentation for the new scenario and harness.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9f7f340f08

ℹ️ 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".

Comment thread versioned/internal/process/manager.go Outdated
snevolin added 3 commits July 18, 2026 00:10
Register a request in the lifecycle inflight counter before checking
the draining flag. Requests that race with drain are now either visible
to versiond or rejected with their temporary count removed.

Cover the rejection path by asserting drain status returns to zero.
Replace string routes with generation-specific proxy targets that lease
each forwarded request. Retired targets reject stale acquisitions while
already acquired requests remain pinned to the old child.

Wait for old proxy leases before requesting child drain, using the same
VERSIOND_DRAIN_TIMEOUT for proxy and lifecycle phases. Apply the gate to
rolling swaps and removed versions.

Cover target retirement, stale-route retry, route-swap continuity, and
manager drain ordering. Update the rolling update design.
Keep restored approved versions from starting while an older child
with the same name is still draining. Recheck the guard before cached
starts, downloads, download completion, and local override activation.

This prevents multiple generations from sharing a version data
directory after a remove-and-readd sequence. Start the restored version
on a later reconcile after the draining child exits.

Cover normal, in-progress download, and override paths. Document the
re-add behavior in the rolling update design.
Comment thread versioned/internal/process/manager.go Outdated
Require the running child path and archive identity to match the local
override before treating equal flat-file contents as already active.

This prevents a stale flat override file from masking a child that is
actually running from a downloaded per-SHA install.

Cover both the stale-file replacement and exact-identity no-op paths.
@x0152

x0152 commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

The idea is right, some hardening might be needed, but it's non-blocking

snevolin added 4 commits July 18, 2026 02:52
Resolve verified binaries from both per-SHA and legacy flat layouts.
Atomically copy matching legacy installs into the canonical per-SHA
directory before starting a child, without requiring network access.

Publish install metadata only after verifying the promoted binary and
retain the flat source for older supervisors sharing the bin mount.
Fall back to the re-verified flat binary when promotion cannot write.

Cover successful, concurrent, failed, and invalid promotion paths.
Document the upgrade and shared-mount behavior.
Replace CommandContext, WaitDelay, and competing child wait timers
with a single process owner that moves through running, terminating,
killing, and exited states.

Send SIGTERM to the child process group and escalate to SIGKILL after
the configured grace period. Close completion only after cmd.Wait has
reaped the process.

Make manager shutdown stop all children first. Use its context only to
force escalation without abandoning process ownership or reap.

Cover graceful exit, forced escalation, and shutdown-deadline
behavior. Document the process-level contract and its boundary with
the future host evacuation FSM.
Gate the child Starting-to-Running transition on logical admin
readiness and public HTTP health. Recheck both conditions within one
VERSIOND_READY_TIMEOUT. This prevents early admin readiness from
hiding a delayed or failed public bind.

Keep legacy readiness fallback only for children without the admin API.
Require modern children to return 200 from the configured admin path
and 2xx from public /healthz before publishing their route.

Cover unavailable public listeners and readiness changes between probe
attempts. Document the combined promotion gate.
Replace the -1 exhaustion sentinel with an explicit error and
propagate it through cached, downloaded, override, and replacement
child starts.

Stop admin-capable children before exec when their second port cannot
be allocated, release the public port, and keep the current rolling
target active when replacement allocation fails.

Cover pool exhaustion, publication guards, and admin-port cleanup.
Document the failure behavior.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e586a2df57

ℹ️ 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".

return fmt.Errorf("create replacement version %s: %w", v.Name, startErr)
}
m.mu.Unlock()
go m.runChild(newChild.ctx, newChild.child)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Track replacement children before readiness waits

When a rolling swap starts the replacement child here, it is not added to m.processes or m.draining until after readiness succeeds at the later swap point. If versiond is shutting down while waitForChildReady is pending, Manager.Shutdown only snapshots those maps, so it can stop/wait for the old child and return without waiting for or force-killing this already-started replacement; in the main shutdown path the signal context may have sent SIGTERM, but versiond can still exit before this goroutine reaps or escalates a child that is slow or ignores SIGTERM. Keep pending replacement children in a tracked set that Shutdown also stops and waits on before starting the process.

Useful? React with 👍 / 👎.

snevolin added 2 commits July 18, 2026 23:09
Merge four new commits from
origin/ak/pixelplex-refactoring-into-r2. They add the S9 validation
lease race, sticky-session failover, gRPC settlement confirmation, and
edge-api release wiring.

Keep upstream S9 as the numbered validation scenario. Rename the local
rolling-update test and its helpers to VersiondRollingUpdate, add the
citest-versiond-rolling-update target, and update testenv docs.

Resolve endpoint discovery around Docker-assigned host ports so the
new S9 topology and rolling-update stacks both use published addresses.
Replace S1-S9 identifiers in citest file names, test functions,
harness helpers, temporary resources, and Make targets with
behavior-oriented names.

Keep citest-stack selecting the same scenarios, add the descriptive
citest-validation-lease-race target, and update testenv documentation
and plans to use the new names.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb2177765d

ℹ️ 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".

Comment on lines +741 to +742
old.Stop()
waitForChild(old)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Retire the old target before fallback stop

When rolling overlap is disabled for SQLite/hybrid or legacy-storage devshard children, this branch sends SIGTERM while the old child remains in m.processes and the route table until waitForChild returns. Requests that already acquired, or newly acquire during the shutdown grace, the old proxy target can be forwarded after the child has entered drain or closed its listener, so accepted work can fail instead of draining; unlike the overlap/removal paths, this fallback never retires the target before stopping the child. Move the old child out of routes and wait for proxy leases before calling Stop().

Useful? React with 👍 / 👎.

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.

3 participants