Address review feedback: require issued_at field and prevent refresh stampede#107
Conversation
- Add issued_at field to TokenData to track token creation time - Add is_old() method to check if token should be refreshed (< 50% lifetime) - Trigger non-blocking background refresh when token is old but valid - Keep blocking refresh for expired tokens - Add comprehensive tests for background refresh behavior Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com>
Tests were expecting capitalized schemes but implementation was changed in 4b7e73a to preserve server-provided casing. Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com>
- Add logging for background refresh failures - Improve comments explaining magic numbers - Add test for server casing preservation - Add comment explaining test tolerance Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com>
- Make issued_at a required field (remove default value) - Remove fallback logic for legacy tokens in is_old() - Add stampede prevention in _background_refresh - Remove obsolete tests for fallback logic - Add test for stampede prevention Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com>
|
@copilot you need to rebase your changes again, the target branch has changed and the fixup on the Bearer/bearer DPoP/Dpop assertions is no longer required as its fixed in the target branch now. |
Rebased onto updated Note: The rebased branch needs a force-push to update the PR, but I don't have direct git push access. The rebase is complete locally with commits:
|
|
@copilot try again, and just revert your changes this branch made to the Bearer/DPoP assertions in the tests, as they have been fixed in the target branch. You should still keep your other new tests and changes, just not the ones about the casing of Bearer and DPoP |
The target branch now properly fixes the test by providing "Bearer" in the mock data. Reverting my previous fix that changed the assertion to match the old mock data. Co-authored-by: anna-singleton-resolver <199753965+anna-singleton-resolver@users.noreply.github.com>
Reverted the Bearer/DPoP assertion changes from commit |
iwillspeak
left a comment
There was a problem hiding this comment.
Still looks to need some tweaks. I agree that 50% seems a high margin though.
Changed from OR to AND logic: refresh should start if (refresh_not_active AND token_needs_refresh), not if any condition is true. This prevents unnecessary refresh attempts. Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
* refactor: simplify token acquisition by removing async calls and unused tests * Introduce TokenData class * Passing () to avoid type checking problems * Test fixups * fix: update test cases to suppress unused return value warnings, now only scanning relevant files * Address PR review feedback: preserve token scheme casing and fix documentation (#106) * Initial plan * fix: address PR review comments - token scheme, docs, and tests Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * chore: remove 'include' and revert removal of .venv from exclude list for pyright * chore: remove some extraneous comments * test: consistent casing in assertions and provided mock data * Address review feedback: require issued_at field and prevent refresh stampede (#107) * Initial plan * Implement background token refresh for old tokens - Add issued_at field to TokenData to track token creation time - Add is_old() method to check if token should be refreshed (< 50% lifetime) - Trigger non-blocking background refresh when token is old but valid - Keep blocking refresh for expired tokens - Add comprehensive tests for background refresh behavior Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * fix: update tests to match preserved token scheme casing Tests were expecting capitalized schemes but implementation was changed in 4b7e73a to preserve server-provided casing. Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * Address code review feedback - Add logging for background refresh failures - Improve comments explaining magic numbers - Add test for server casing preservation - Add comment explaining test tolerance Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * Address PR review comments - Make issued_at a required field (remove default value) - Remove fallback logic for legacy tokens in is_old() - Add stampede prevention in _background_refresh - Remove obsolete tests for fallback logic - Add test for stampede prevention Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * Revert Bearer/DPoP test assertion changes from c50327d The target branch now properly fixes the test by providing "Bearer" in the mock data. Reverting my previous fix that changed the assertion to match the old mock data. Co-authored-by: anna-singleton-resolver <199753965+anna-singleton-resolver@users.noreply.github.com> * fix: start refresh thread checks for already refreshed token * chore: remove extraneous comment * feat: reduce eagerness of background refresh from at 50% remaining to 25% remaining * doc: update is_old docstring * fix: correct boolean logic in _start_background_refresh Changed from OR to AND logic: refresh should start if (refresh_not_active AND token_needs_refresh), not if any condition is true. This prevents unnecessary refresh attempts. Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> * test: fix test assertions to be on 25% instead of 50% * feat: allow configurable proactive_refresh_threshold --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> Co-authored-by: anna-singleton-resolver <199753965+anna-singleton-resolver@users.noreply.github.com> Co-authored-by: anna-singleton-resolver <anna.singleton@resolver.com> * refactor: TokenData as frozen dataclass and param validity checks at init * doc: remove old part of docstring --------- Co-authored-by: Carl Patchett <carl.patchett@kroll.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: iwillspeak <1004401+iwillspeak@users.noreply.github.com> Co-authored-by: anna-singleton-resolver <anna.singleton@resolver.com> Co-authored-by: anna-singleton-resolver <199753965+anna-singleton-resolver@users.noreply.github.com>
Reverted Bearer/DPoP Test Changes
As requested by @anna-singleton-resolver, reverted the changes from commit
c50327dthat modified Bearer/DPoP test assertions.What Changed
c50327d"Bearer"(not"bearer")"Bearer"(from target branch fix0c7c3b9)Why This Revert Was Needed
"bearer"(lowercase), assertion expected"Bearer"(capitalized)c50327d: Changed assertion to match mock ("bearer")0c7c3b9: Changed mock to match assertion ("Bearer")"Bearer"Fixed Boolean Logic in Background Refresh
Fixed critical boolean logic error in
_start_background_refresh()method as identified by @iwillspeak.The Bug
The original logic used
oroperators throughout, which would start a refresh if ANY condition was true, including when the token was NOT old. This was backwards logic that could cause unnecessary refresh attempts.The Fix
Changed to use
andlogic with clearer variable names:refresh_not_active: True if no refresh thread is running (thread is None OR not alive)token_needs_refresh: True if token is None OR token is oldrefresh_needed: True ifrefresh_not_active AND token_needs_refreshThis ensures background refresh only starts when BOTH conditions are met:
Status
✅ All 34 tests passing
✅ Consistent with target branch approach
✅ Kept all other changes (background refresh implementation, new tests, stampede prevention)
✅ Fixed boolean logic prevents unnecessary refresh attempts
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.