Migrate oc_chef_authz_cleanup from gen_fsm to gen_statem - #4240
Open
tas50 wants to merge 1 commit into
Open
Conversation
gen_fsm has been deprecated since OTP 20. On OTP 28 the compiler emits
deprecated-callback warnings for every gen_fsm callback the module
implements, and because oc_erchef builds with warnings_as_errors this
turns into a hard build failure:
oc_chef_authz_cleanup.erl:31:2: the callback gen_fsm:init(_) is
deprecated; use the 'gen_statem' module instead
The existing -compile(nowarn_deprecated_function) does not silence
these, as it only covers deprecated function calls, not deprecated
callbacks. OTP 26 and 27 are unaffected; OTP 28 is where it breaks.
Translation of the behaviour:
* state_functions callback mode, so stopped/2 and started/2 become
stopped/3 and started/3 with a leading event type.
* send_event/send_all_state_event become gen_statem:cast/2 and
sync_send_all_state_event becomes gen_statem:call/3. gen_statem
routes every event to the current state function, so the former
handle_event/3, handle_sync_event/4 and handle_info/3 bodies are
consolidated into handle_common/3, which each state function falls
through to.
* The prune timer moves from gen_fsm:start_timer/2 to
erlang:start_timer/3, keeping the existing timer_ref field and the
{timeout, Ref, prune} message shape, now delivered as an info event.
State names, transitions, the public API and the #state{} record are
unchanged, so oc_chef_authz_sup and the callers in
oc_chef_authz_scoped_name need no changes.
Verified by compiling the module with -Werror on OTP 26, 27 and 28
(clean on all three; it fails on 28 before this change), and by
exercising the module against stubbed envy/oc_chef_authz on OTP 26 and
28 to confirm initial state, set union on add_authz_ids, batch-size
limited pruning, automatic pruning after start/0, timer cancellation on
stop/0 and tolerance of unknown events all behave as they did under
gen_fsm.
Signed-off-by: Tim Smith <tim@mondoo.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
oc_chef_authz_cleanupis the lastgen_fsmin the tree.gen_fsmhas been deprecated since OTP 20, and on OTP 28 the compiler emits a deprecated-callback warning for everygen_fsmcallback the module implements:src/oc_erchef/rebar.configsetswarnings_as_errors, so this is not cosmetic — it is a hard build failure on OTP 28.The module already carries
-compile(nowarn_deprecated_function), but that option only suppresses deprecated function calls; it does not suppress deprecated callbacks, so it does not help here.Measured with
erlc -Werroragainst the officialerlang:{26,27,28}-alpineimages:So the current pin (
{require_otp_vsn, "26.2.5.21"}) is safe today, but this module blocks a move to OTP 28.What changed
Only
oc_chef_authz_cleanup.erl. The behaviour is translated, not redesigned:state_functionscallback mode, sostopped/2andstarted/2becomestopped/3andstarted/3with a leading event type. State names and every transition are unchanged.send_event/send_all_state_event→gen_statem:cast/2, andsync_send_all_state_event→gen_statem:call/3.gen_statemroutes all events to the current state function, so the oldhandle_event/3(all-state),handle_sync_event/4(all-state sync) andhandle_info/3bodies are consolidated into a singlehandle_common/3that each state function falls through to.gen_fsm:start_timer/2toerlang:start_timer/3. This deliberately keeps the existingtimer_reffield and the{timeout, Ref, prune}message shape (now arriving as aninfoevent) rather than switching togen_statem's built-in state/named timeouts, to keep the diff small and the semantics identical — including the existing behaviour where a stray prune timeout that fires whilestoppedis ignored and not re-armed. Happy to switch to nativegen_statemtimeouts if you'd prefer the more idiomatic form.The public API, the state names, and the
#state{}record are all unchanged, sooc_chef_authz_supand the caller inoc_chef_authz_scoped_nameneed no changes, andoc_chef_authz_cleanup_testsneeds no changes.Verification
Compilation —
erlc -Werroron OTP 26, 27 and 28: clean on all three (OTP 28 fails onmain).Behaviour — because this is a behaviour swap rather than a logic change, I exercised the module directly against stubbed
envyandoc_chef_authzmodules on both OTP 26 and OTP 28, and ran the same assertions against the unmodifiedgen_fsmversion on OTP 26 to confirm equivalence. All of the following pass identically before and after:add_authz_ids/2stores actors/groups, and unions with what is already thereadd_authz_ids/2still works in thestartedstate (i.e. the former all-state event is handled from every state)prune/0deletes viaoc_chef_authz:delete_resource/3with the correctactor/grouptype and superuser idprune/0honourscleanup_batch_size(10 of 25 removed, 15 left)start/0and prunes on its ownstop/0cancels the timer and no further pruning happensok