fix(scheduler): re-pushed resource definitions are not errors (bug-1854)

Every scheduler (re)join re-pushes the whole config, and both apply paths
-- sched_init_resources() (scheduler.c) and core_apply_config_resources()
(core_events.c) -- re-added each resource with makeResource(), which
refuses an existing name: one ERROR per resource per rejoin (33 in
data/xce_scheduler.log), and a genuinely changed definition was dropped
just as silently.

New libxce resourceApplyDef(): under one write lock, register a new
resource (ADDED), or compare an already-registered one on its
scheduling-relevant fields -- valtype, ordtype, flags, interval -- and
return SAME or CHANGED. Both call sites log SAME at debug, CHANGED as a
WARN that the definition is not applied to the running scheduler
(updating a registered resource in place would disturb its index and
accounting), and only real failures as ERROR.

Test test_resource_reapply_same_is_noop_changed_is_reported (EEXIST on
an identical re-push before). Scheduler suite 87/87, lib 1/1. Re-verify
of data/scheduler-replay-20260925-133708.replay: 0 add-resource ERRORs
(33 before), 0 changed-definition WARNs, 0 mismatches, same 60 DISPATCH /
908 PEND decisions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-09-25 15:09:49 +00:00
parent 6b1862f8d3
commit 663ea63cc5
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
5 changed files with 113 additions and 9 deletions

View file

@ -149,3 +149,40 @@ xce_resource_t* makeResource(var resmgr, xce_resource_t* r)
return r1;
}
/* bug-1854: register a pushed resource definition, tolerating re-pushes.
* Every scheduler (re)join re-pushes the whole config; makeResource() refuses
* an existing name, so callers logged one ERROR per resource per rejoin and
* a genuinely changed definition was dropped just as silently. Only the
* scheduling-relevant fields are compared (idx/last_report are runtime
* state, desc is cosmetic); a changed definition is reported but NOT
* applied -- updating a registered resource in place would disturb its
* index and accounting. Lookup and add happen under one write lock. */
int resourceApplyDef(var resmgr, xce_resource_t* r)
{
xce_resource_t* cur = NULL;
int rc;
if ((resmgr == NULL) || (r == NULL) || (r->name == NULL)) {
return -EINVAL;
}
lock(resmgr, RTTI_LOCK_WRITE);
rc = key_find(resmgr, (void*)r->name, (void**)&cur);
if ((rc > 0) && (cur != NULL)) {
int same = (cur->valtype == r->valtype) && (cur->ordtype == r->ordtype)
&& (cur->flags == r->flags) && (cur->interval == r->interval);
unlock(resmgr);
return same ? RES_APPLY_SAME : RES_APPLY_CHANGED;
}
if ((rc < 0) && (rc != -ENOENT)) {
unlock(resmgr);
return rc;
}
cur = makeResource_(resmgr, r);
unlock(resmgr);
return (cur != NULL) ? RES_APPLY_ADDED : -errno;
}