Repository navigation
refactor(account): share the entry scope of FinishAsync and SetScrobblingAsync - #281
Conversation
…lingAsync FinishAsync and SetScrobblingAsync started with the same seven statements: caller and host-access checks, the current authorization, a token linked to it, and the per-user account gate. They now call one private EnterAccountAsync helper that returns an AccountScope. Disposing the scope releases the gate first and then the linked token, the same order the two using declarations had. If the gate wait throws, the linked token is disposed as before. BeginAsync keeps its own steps: it validates the callback between the host-access check and the authorization lookup, and moving that would change which error a disabled user with a bad callback sees. Tests pin the folded behaviour: a disabled host user is refused by FinishAsync and SetScrobblingAsync, and a scrobbling change waits for a pending grant's gate and is cancelled when the account disconnects. Signed-off-by: lusoris <lusoris@proton.me>
The new scrobbling-gate test ended with the same three checks as DisconnectImmediatelyCancelsPendingGrantAndCannotBeUndoneByItsResponse: the released grant ends cancelled, the disconnect finishes, and the account is gone. The clone scan reported the two tails as one 9-line group. Both tests now call AssertGrantCancelledAndDisconnectedAsync. Signed-off-by: lusoris <lusoris@proton.me>
Reviewer's GuideImplementationFactor shared caller and host checks, authorization-linked cancellation, and account-gate acquisition into an AccountScope used by FinishAsync and SetScrobblingAsync, while preserving disposal order and gate-wait cleanup.
TestsCover the shared account-entry behavior with cancellation and disconnect concurrency checks, plus disabled-host rejection and BeginAsync callback-validation ordering.
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 8 |
| Duplication | 0 |
AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Pull Request Overview
✅ No blocking issues noticed
No blocking code findings were identified. The required scenarios for failed gate acquisition cleanup and preservation of BeginAsync validation ordering are still missing, so these behaviors should be covered before merging.
Test suggestions
- A disabled host user is rejected by FinishAsync and SetScrobblingAsync.
- SetScrobblingAsync waits for a pending grant and is cancelled by disconnect.
- FinishAsync is cancelled and the account is removed when disconnect occurs during a pending grant.
- AccountScope releases the gate before its linked cancellation source is disposed.
- Failed gate acquisition disposes the linked cancellation source.
- BeginAsync preserves its callback-validation ordering for disabled users.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Failed gate acquisition disposes the linked cancellation source.
2. BeginAsync preserves its callback-validation ordering for disabled users.
TIP How was this review? Give us feedback
A scrobbling change whose wait for the account gate is cancelled now has a test: the gate stays free, and a later change still applies. BeginAsync now has a test showing that it refuses a disabled host user before it checks the return address and that it stores no attempt. Both tests answer the Codacy review of this pull request. Moving the host check after the callback check fails the second test, and releasing a gate the waiter never held fails the first. Signed-off-by: lusoris <lusoris@proton.me>
The cancelled-wait test now cancels eight scrobbling changes in a row while a pending grant holds the account gate. Eight is the gate pool's per-user limit for ordinary waiters, so a cancelled wait that kept its slot would make the last round fail with "Too many concurrent account changes" instead of a cancellation. Without this, a pool that never gave the slot back passed all 769 tests; with it, that change fails the test. Both new tests also gain a one-line summary. Signed-off-by: lusoris <lusoris@proton.me>
Signed-off-by: lusoris <lusoris@proton.me>
|
Both missing tests are added in 376f8ef and cd12211.
Each test was checked against a source change it should catch, running the full suite of 769 tests each time:
With the sources restored, all tests pass. |
Change
FinishAsyncandSetScrobblingAsyncinAccountServicenow enter an account call through one private helper. Before this change, both started with the same seven statements: the caller check, the host-access check, the current authorization, a token linked to that authorization, and the per-user account gate. The duplicate-code scan reported the two copies as one 9-line clone group.EnterAccountAsyncruns those steps and returns anAccountScopethat carries the operation, the authorization and the linked token. Disposing the scope releases the gate first and then the linked token, the same order the twousingdeclarations had. If the gate wait throws, the linked token is disposed, as before.BeginAsynckeeps its own steps.FinishAsyncandSetScrobblingAsynceach have a one-line<summary>.No account, configuration, plugin API or Plugin Repository behaviour changes.
Validation
praetorctl dedupe scan --json(jscpd 5.4.2). At6c056aeit reports 111 groups, one of them inAccountService.cs(:175 and :324, 9 lines). With this change it reports 110 groups and none in the Account sources or tests. The first version of the new concurrency test repeated the tail of an existing test and added a 9-line group inAccountConcurrencyTests.cs; the second commit moves those checks intoAssertGrantCancelledAndDisconnectedAsync, and the group is gone.DisabledHostUserCannotContinueBackgroundOperationsnow also checks that a disabled host user is refused byFinishAsyncandSetScrobblingAsync.ScrobblingChangeWaitsForAPendingGrantAndEndsWithDisconnectchecks that a scrobbling change waits while a pending grant holds the account gate, and that a disconnect cancels it while the gate is still held.DisabledHostUserCannotContinueBackgroundOperations.AccountConcurrencyTests.ScrobblingChangeWaitsForAPendingGrantAndEndsWithDisconnect.CancelledScrobblingWaitLeavesTheAccountGateFreecancels eight scrobbling changes in a row while a pending grant holds the account gate, then shows a further change applies, so a failed gate wait gives back both the gate and its waiter slot.DisabledHostUserIsRefusedBeforeTheCallbackIsCheckedshowsBeginAsyncrefuses a disabled user withUnauthorizedAccessExceptionbefore it rejects an invalid return address, and stores no attempt. On the full suite of 769 tests, each source change below fails at least one of them, and the restored code passes all 769:BeginAsyncfailsDisabledHostUserIsRefusedBeforeTheCallbackIsChecked.CancelledScrobblingWaitLeavesTheAccountGateFreeamong them.CancelledScrobblingWaitLeavesTheAccountGateFree; with only one cancelled round it passed all 769 tests, hence eight rounds.make verify-allon5ed3ca6(cd12211merged withmain) exits 0, with dotnet and npm in the pinned SDK container (tools/sdk.sh): 0 build warnings, 769 .NET tests and 450 Python tests pass. It also prints four pre-existing HISS-18 draft-trigger warnings forci.ymlandcodeql.yml; that rule reports and does not enforce, and this change does not touch either file.Summary by Sourcery
Centralize the account-operation entry scope and strengthen tests for authorization, cancellation, gating, and disabled-user behavior.
Enhancements:
Tests:
Summary by CodeRabbit