Skip to content

fix: live in-place apply commits running-processor config (§4 blocker, Tier 1)#2617

Merged
devarismeroxa merged 2 commits into
mainfrom
fix/inplace-running-processor-update
Jul 13, 2026
Merged

fix: live in-place apply commits running-processor config (§4 blocker, Tier 1)#2617
devarismeroxa merged 2 commits into
mainfrom
fix/inplace-running-processor-update

Conversation

@devarismeroxa

Copy link
Copy Markdown
Contributor

What

Fixes the blocker the #2616 review found: the §4 in-place hot-reload never worked end-to-end. applyInPlace (PR1, #2613) committed the new processor config through processor.Service.Update, whose running-instance guard refused it (ErrProcessorRunning), so ApplyPlanLive returned the error and ReconfigureProcessor — the actual live swap — was never reached. PR1's mock-based tests returned success for the mocked Update and hid it; PR2's real-engine integration test exposed it.

Risk tier: 1 (data path). DeVaris pre-approved this approach (Option A); requesting sign-off on the diff + the failure-mode analysis below.

Fix (Option A)

  • processor.Service.UpdateWhileRunningUpdate minus the running guard — for provisioning's live-reconfigure only. Update keeps the guard for direct API/orchestrator callers (who do not swap the node).
  • updateProcessorAction routes through UpdateWhileRunning. Safe for both provisioning paths: restart = processor stopped (equivalent to Update); in-place = the node is immediately swapped by ReconfigureProcessor to match the committed config.
  • Provisioning ProcessorService interface swapped UpdateUpdateWhileRunning (its only caller was this action); mock regenerated.

Failure-mode analysis

  • Could this let a running processor's config diverge from its node? Only if UpdateWhileRunning were called without a swap. Its sole caller (updateProcessorAction via applyInPlace) always pairs it with ReconfigureProcessor (in-place) or a full rebuild on Start (restart). Documented as an invariant on the method. Direct API callers still hit Update's guard.
  • Regression coverage: TestService_UpdateWhileRunning_BypassesRunningGuard proves Update refuses a running instance and UpdateWhileRunning commits; provisioning apply/import tests assert the engine now calls UpdateWhileRunning; the real end-to-end assertion is PR2's tightened integration test.
  • Rollback: additive method + a one-line action change; reverting restores the prior (non-functional-in-place) behavior. No serialized-format change.
  • pkg/orchestrator (the API Update caller) verified unchanged and green.

Adversarial self-review

Re-read for: the guard staying intact for orchestrator/API (yes), UpdateWhileRunning being paired with a node swap at every call site (yes), the restart path unaffected (processor stopped → equivalent), and the rollback path (transactionalImport(oldConfig) also now uses UpdateWhileRunning, so it works on a running pipeline too).

Unblocks #2616 (PR2). Roadmap §4.

🤖 Generated with Claude Code

https://claude.ai/code/session_01B3cLokwNJYLLBpdyt3cgGr

…essor config

The in-place hot-reload path (PR1, #2613) never worked end-to-end: applyInPlace
committed the new processor config through processor.Service.Update, whose
running-instance guard (ErrProcessorRunning) refused it, so ApplyPlanLive returned
the error and lifecycle.ReconfigureProcessor — the actual live swap — was never
reached. PR1's mock-based tests returned success for the mocked Update and hid it;
PR2's real-engine integration test exposed it (found in the #2616 review).

Fix (Option A): add processor.Service.UpdateWhileRunning — Update minus the
running guard — and route provisioning's updateProcessorAction through it. This is
safe for both provisioning paths: the restart path applies it on a stopped
pipeline (processor not running, so equivalent to Update), and the in-place path
immediately swaps the live node via ReconfigureProcessor to match the committed
config. Update keeps its guard for direct API/orchestrator callers, who do NOT
swap the node (verified: pkg/orchestrator still uses Update).

Regression test: TestService_UpdateWhileRunning_BypassesRunningGuard — Update
refuses a running instance (ErrProcessorRunning); UpdateWhileRunning commits the
config. The provisioning apply/import tests now assert the engine calls
UpdateWhileRunning. The full real-engine end-to-end assertion lives in PR2's
tightened integration test.

Risk tier 1 (data path). Failure-mode analysis in the PR. Fixes the §4 in-place
hot-reload blocker; unblocks PR2 (#2616).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3cLokwNJYLLBpdyt3cgGr
@devarismeroxa
devarismeroxa requested a review from a team as a code owner July 13, 2026 19:45
…ateProcessorAction

Review NIT on #2617.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B3cLokwNJYLLBpdyt3cgGr
@devarismeroxa
devarismeroxa merged commit ae12acc into main Jul 13, 2026
5 checks passed
@devarismeroxa
devarismeroxa deleted the fix/inplace-running-processor-update branch July 13, 2026 19:59
devarismeroxa added a commit that referenced this pull request Jul 13, 2026
Adds `conduit run --dev`: a file watcher that hot-reloads pipeline config edits
into a running engine. On a watched YAML change it debounces, re-plans, and
applies via provisioning.ApplyPlanLive — an in-place processor swap when the
diff is live-eligible (no restart), else a graceful drain-and-restart. Reports
the engine's true applied mode (in_place/restart/provisioned) per edit, with
--dev.json structured events and stable error codes.

Completes ROADMAP §4 (hot-reload / dev), building on the engine live-reconfigure
work (#2617, #2619).

Independent review clean (both prior blockers — in-place non-functional and a
shutdown race — verified fixed). Hardening applied from review: apply-goroutine
panic containment (a bad edit never crashes the server / live pipelines),
always-tear-down debouncers on shutdown, and no fresh apply started mid-teardown.
Full-engine integration test asserts real mode:in_place with zero restart. Docs:
docs/operations/dev-hot-reload.md runbook + design doc.
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.

1 participant