CFE-4681: default timer_policy => reset for classes: promises (3.28.0)#6174
CFE-4681: default timer_policy => reset for classes: promises (3.28.0)#6174nickanderson wants to merge 3 commits into
Conversation
…ntSave ValueSizeDB() was called with strlen(key), but WriteDB(), ReadDB() and DeleteDB() store and look up keys with strlen(key) + 1 (including the terminating NUL), and LMDB matches keys by exact byte length. The lookup therefore never found the stored record and always reported size 0. Passing strlen(key) + 1 makes the lookup match the key as written. This lets EvalContextHeapPersistentSave() find an existing record and act on it: preserve an already-set, unexpired timer (CONTEXT_STATE_POLICY_PRESERVE) and log "Resetting" rather than "Creating" on a RESET save. Ticket: CFE-4681 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@cf-bottom jenkins please |
|
Alright, I triggered a build: Jenkins: https://ci.cfengine.com/job/pr-pipeline/13944/ Packages: http://buildcache.cfengine.com/packages/testing-pr/jenkins-pr-pipeline-13944/ |
Add a timer_policy attribute to classes: promises, controlling whether a
persistent class timer resets on re-evaluation ("reset") or preserves the
original expiry ("absolute"). Defaults to "absolute" for backward
compatibility; planned to change to "reset" in 3.28.0 to match classes
bodies, keeping "absolute" on the 3.24 and 3.27 LTS backports.
timer_policy without persistence is now an error, since it only governs
the persistence timer.
Ticket: CFE-4681
Changelog: Title
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CFE-4681 added a timer_policy attribute to classes: promises with the default "absolute" (preserve) for backward compatibility. For 3.28.0 the default becomes "reset", aligning classes: promises with classes bodies (whose timer_policy has always defaulted to reset) and matching the common expectation that a persistent class which keeps being rediscovered should keep persisting rather than lapsing. - GetContextConstraints(): default the resolved timer policy to RESET; only an explicit timer_policy => "absolute" selects PRESERVE. - ExpandDeRefPromise(): an already-defined persistent class is no longer skipped unless timer_policy => "absolute" is set, so the default reset can refresh the timer. - Update the classes: promise syntax doc default to "reset". - Acceptance test persistent_timer_policy_default.cf: a classes: promise with no timer_policy resets the timer on a subsequent run. This is a master-only change. The timer_policy attribute itself is being backported to the 3.27.x and 3.24.x LTS streams (3.27.2, 3.24.5) with the long-standing "absolute" default preserved, so behavior there is unchanged and reset remains opt-in. Ticket: CFE-4681 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
07657cc to
c5ab252
Compare
|
@cf-bottom jenkins please |
|
Alright, I triggered a build: Jenkins: https://ci.cfengine.com/job/pr-pipeline/13948/ Packages: http://buildcache.cfengine.com/packages/testing-pr/jenkins-pr-pipeline-13948/ |
craigcomstock
left a comment
There was a problem hiding this comment.
Really the only thing I think is "required" to change is adding Changelog to the last commit which changes the default timer_policy for classes promises to reset.
| // first see if we have an existing record, and if we should bother to update | ||
| { | ||
| int existing_info_size = ValueSizeDB(dbp, key, strlen(key)); | ||
| int existing_info_size = ValueSizeDB(dbp, key, strlen(key) + 1); |
There was a problem hiding this comment.
Seems like we should avoid having to provide a +1 to a parameter and maybe fix the ValueSizeDB() function instead somehow. Maybe a wrapper function for lookup that normalizes the information so code is easier to write/read?
There was a problem hiding this comment.
Yeah maybe, but probably in some other pr.
| { | ||
| const char *tp = PromiseGetConstraintAsRval(pp, "timer_policy", RVAL_TYPE_SCALAR); | ||
| if (StringEqual(tp, "reset")) | ||
| if (StringEqual(tp, "absolute")) |
There was a problem hiding this comment.
I see no Changelog in this "Changed default timer_policy for classes: promises to reset" commit. Better fix that I think.
| bundle agent check | ||
| { | ||
| classes: | ||
| "first_ok" expression => regline(".*Creating persistent class.*timer_default_test_class.*", |
There was a problem hiding this comment.
Relying on a log message seems brittle. Do you have references here and in the code where the message lies to leave a breadcrumb trail for future code/test changes?
Maybe it would be better to investigate the LMDB database and check timestamps there? That would check the "truth" at the "source" right?
Summary
Flips the default
timer_policyforclasses:promises fromabsolutetoresetfor 3.28.0.#6167 introduced the
timer_policyattribute onclasses:promises with a default ofabsolute(preserve) for backward compatibility. This PR changes that default toresetso that:classes:promises align withclassesbodies, whosetimer_policyhas always defaulted toreset.Setting
timer_policy => "absolute"explicitly restores the previous skip-and-preserve behavior.This branch is based on
CFE-4681/timer-policy-classes-promises(the #6167 head), so until #6167 merges tomasterthis PR's diff shows both. The change unique to this PR is the final commit,07657cce4.The
timer_policyattribute is being backported to the LTS streams (3.27.2, 3.24.5) with the long-standingabsolutedefault preserved, so behavior on those releases is unchanged andresetstays opt-in there. This default flip is intentional for 3.28.0 only.Changes
GetContextConstraints()(attributes.c): resolve the timer policy toRESETby default; only an explicittimer_policy => "absolute"selectsPRESERVE.ExpandDeRefPromise()(promises.c): an already-defined persistent class is no longer skipped unlesstimer_policy => "absolute"is set, so the defaultresetcan refresh the timer.mod_common.c: syntax doc default for theclasses:promisetimer_policyupdated toreset.persistent_timer_policy_default.cf: aclasses:promise with notimer_policyresets the timer on a subsequent run.Test plan
libpromisescompiles clean (full-binary link blocked locally by an unrelated ASan toolchain issue; relying on CI for the binary build + acceptance run)persistent_timer_policy.cf(explicitabsolute→ still skipped) and the newpersistent_timer_policy_default.cf(default → reset)Ticket: CFE-4681