fix: PowerProfile — powerprofilesctl/tlpctl support, fallback, and race condition fixes#89
Open
saken78 wants to merge 1 commit intoAxenide:mainfrom
Open
fix: PowerProfile — powerprofilesctl/tlpctl support, fallback, and race condition fixes#89saken78 wants to merge 1 commit intoAxenide:mainfrom
saken78 wants to merge 1 commit intoAxenide:mainfrom
Conversation
…(fallback). Supports optimistic UI updates with automatic rollback on failure and stale-read protection.
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.
PowerProfile Service — Changelog
Manages power profiles via
powerprofilesctl(primary) ortlpctl(fallback).Supports optimistic UI updates with automatic rollback on failure and stale-read protection.
Execution Flow
Initial Load
Set Profile
Stale-Read Protection
Any read arriving in
getProc.onReadorgetTLPProc.onReadwhile_isSettingProfile = trueand the returned profile ≠_expectedProfileis silently discarded. This prevents a slow backend response from
overwriting the optimistic update with the old value.
test3
Fix:
_expectedProfileis now reset to""after a successful set.Previously the filter remained active indefinitely, causing subsequent
valid reads (e.g. from
updateCurrentProfile()) to be silently discardedif the profile happened to differ from the last set target.
Fix:
checkTLPnow uses onlycommand -v tlpinstead ofcommand -v tlp && tlp --version.tlp --versionrequires root onseveral distributions and returns non-zero even when tlp is correctly
installed, producing a false-negative that silently skipped the fallback.
Fix:
getProc.onExitednow triggerslistProconly on initial load(guarded by
_initialLoadflag). Previously every rollback read after afailed set would also re-run
listProc, which was unnecessary andproduced redundant process spawns.
test2
Fix: Removed the post-success confirmation read in
setProc.onExited.The confirmation
getTLPProc/getProccall was issued viaQt.callLaterimmediately after set, racing against the backend applying the change and
consistently returning the stale pre-change value, which then overwrote the
correct optimistic state.
Fix: Added
_isSettingProfile+_pendingProfileguard insetProfile.setProcis now never re-triggered while still running. If a second setrequest arrives during an in-flight operation, it is stored in
_pendingProfileand processed automatically insetProc.onExited.Fix: Added
_expectedProfilestale-read filter ingetProc.onReadandgetTLPProc.onRead. Reads arriving while a set is in-flight are comparedagainst
_expectedProfileand discarded if they do not match, preventingthe backend's delayed response from corrupting the optimistic UI state.
test1
Fix:
checkPowerProfilesCtlandcheckTLPnow use abash -c "command -v …"wrapper instead of invoking the binary directly. Quickshell
Processdoes notgo through a shell; if the binary is absent the OS-level exec fails silently,
onExitednever fires, and the TLP fallback is never reached.Fix:
listProcis now triggered sequentially fromgetProc.onExitedinsteadof via two independent
Qt.callLatercalls incheckPowerProfilesCtl.onExited.The original approach started both processes in parallel with no ordering
guarantee, allowing
listProcto overwriteavailableProfilesmid-read.Fix:
listProcfailure no longer resetsbackendTypeto""andre-triggers
checkTLP. Sincepowerprofilesctlwas already confirmed present,the backend is kept and
availableProfilesfalls back to the known-safe defaults["power-saver", "balanced", "performance"].Fix:
setProc.commandis no longer mutated while the process may still berunning. The previous implementation assigned a new command array and immediately
set
running = truewithout checkingsetProc.running, risking a command changemid-execution on rapid successive calls.