fix(controller): a queue added by a live config upgrade exists without a restart (bug-1469)

build_queues() only ran at boot, so a queue a live config upgrade added
had no runtime object in c->qmgr (and the scheduler/apiserver never heard
of it) until the controller restarted. The checkpoint-ordering half of
bug-1469 was fixed in 959b0cda; this is the remaining half.

- reconcile_config_queues(c, notify): creates every queue in the active
  config that has no runtime object, leaves existing ones untouched,
  returns the number created.
- config_activate_committed() calls it (with notify) after every
  successful activation -- verified-marker and no-marker paths alike.
- persist_notify_queue_updated_no_wal(): fires HOOK_DETAIL_QUEUE_UPDATE
  under the t_apply_seam_notifying guard, so the scheduler/apiserver are
  told while no WAL_QUEUE_CTRL is appended -- config queues are
  config-owned, built on every member from the committed config.
- build_queues() now delegates to it without notify, so boot and
  activation are idempotent in either order.

New test_config_queue_reconcile.c (RED before: the added queue was never
created): creates the added queue, leaves the existing object untouched,
notifies once, and a second reconcile/build_queues adds nothing.
Controller suite passes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-09-27 06:05:26 +00:00
parent c3a17b19ab
commit 154a169ff3
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
8 changed files with 183 additions and 5 deletions

View file

@ -8192,6 +8192,14 @@ void persist_notify_job_updated_already_persisted(cluster_t* c, job_t* j)
* status changed WITHOUT persist_worker_hook_fun appending a WAL_WORKER_CTRL
* fact for it, since resync.c's XCE_WORKER_RECONCILING coordination bit is
* intentionally never durable. */
void persist_notify_queue_updated_no_wal(cluster_t* c, queue_t* q)
{
t_apply_seam_notifying = true;
xce_run_hooks(&c->hooksys, XCE_CONTROLLER_HOOK_QUEUE, HOOK_AFTER_EVENT,
HOOK_DETAIL_QUEUE_UPDATE, c, q);
t_apply_seam_notifying = false;
}
void persist_notify_worker_status_updated(cluster_t* c, worker_t* w)
{
t_apply_seam_notifying = true;