Skip to content

Fix Auth token refresh slot cleanup race - #16765

Open
dajiaohuang wants to merge 4 commits into
firebase:mainfrom
dajiaohuang:fix/auth-token-refresh-coalescer-generation
Open

dajiaohuang wants to merge 4 commits into
firebase:mainfrom
dajiaohuang:fix/auth-token-refresh-coalescer-generation

Conversation

@dajiaohuang

@dajiaohuang dajiaohuang commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Guard pending refresh-slot cleanup by generation so an older actor call cannot clear a newer in-flight refresh after suspension. The consequence of the race is a redundant token refresh.
  • Add a deterministic regression that observes the pending token immediately after the older task finishes, preserving the newer slot until its own completion.
  • Update the Unreleased changelog with Fix Auth token refresh slot cleanup race #16765.

Validation

  • Actual coalescer and test file compiled in an isolated Linux Swift 6.1.3 package. The selected XCTest fails on the pre-PR coalescer with the same observation accessor and passes on the updated source.
  • Pinned SwiftFormat 0.55.5 lint and git diff --check pass.
  • Apple Xcode 26.4.1/iOS simulator: all 6 real TokenRefreshCoalescerTests pass, including testOlderRefreshCompletionDoesNotClearNewerPendingRefresh. Native validation run checks out the exact PR source 2b2f9d51e203ce54c6f55a42882bfdd4c9e5080a; its workflow is on a separate validation branch.
  • These are focused coalescer tests in the actual FirebaseAuth unit-test target. Full SDK/platform acceptance and upstream workflow approval remain separate.

@gemini-code-assist

Copy link
Copy Markdown
Contributor
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

@paulb777

paulb777 commented Oct 1, 2026

Copy link
Copy Markdown
Member

Thanks for the contribution! A few housekeeping items:

  • CHANGELOG: The entry in FirebaseAuth/CHANGELOG.md is under # 13.0.0, which has already shipped. Please move it under the existing # Unreleased heading at the top of the file.
  • PR number: end the entry with this PR's number, e.g. - [fixed] Description. (#16765).
  • Formatting: after updating, please run scripts/style.sh so the infra.check job passes. It needs clang-format 23 and swiftformat (see scripts/setup_check.sh). If you can't run it locally, the infra.check log lists the files that need formatting.

@paulb777 paulb777 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the actor-reentrancy analysis is right: the older call's defer can clear the newer call's slot, which costs at most one redundant token refresh. The generation check is a minimal, correct fix. One concern about the test inline.

Comment thread FirebaseAuth/Tests/Unit/TokenRefreshCoalescerTests.swift Outdated
@dajiaohuang

Copy link
Copy Markdown
Contributor Author

Replaced the timing-dependent third caller with the suggested internal pendingTokenForTesting accessor. Immediately after the older task completes, the regression checks that the pending token is still token_v2; after the newer task completes, it checks that the slot is empty. The UUID generation implementation remains the minimal fix you confirmed correct; the Task equality alternative is optional.

Compiled the actual coalescer and full test file in an isolated Linux Swift 6.1.3 package. The selected deterministic XCTest fails against the pre-PR coalescer (with only the same observation accessor added), seeing nil instead of token_v2; it passes against the updated coalescer. This is focused actual-source XCTest evidence, not a full FirebaseAuth/Apple build. Moved the changelog under Unreleased/#16765; pinned SwiftFormat 0.55.5 lint and git diff --check pass. Native Apple CI remains required.

@paulb777

paulb777 commented Oct 2, 2026

Copy link
Copy Markdown
Member

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes an issue where an older token refresh completing could clear a newer in-flight token refresh due to actor reentrancy. It introduces a generation identifier to ensure only the matching task clears the pending slot, and adds corresponding unit tests. The review feedback suggests optimizing this mechanism by replacing the UUID generation with a simpler, more efficient monotonically increasing UInt64 counter to avoid unnecessary overhead.

@dajiaohuang

Copy link
Copy Markdown
Contributor Author

The deterministic slot check now also passes in the actual FirebaseAuth Apple unit-test target. On Xcode 26.4.1/iOS simulator, all 6 TokenRefreshCoalescerTests pass, including testOlderRefreshCompletionDoesNotClearNewerPendingRefresh. Native validation run uses this PR's exact source 2b2f9d51e203ce54c6f55a42882bfdd4c9e5080a with a separate validation-only workflow. The earlier actual-source Linux before/after result remains unchanged; this adds native Apple test evidence without changing the PR source or claiming a full platform matrix pass.

@dajiaohuang

Copy link
Copy Markdown
Contributor Author

Merged current upstream main normally in d15604c, resolving the CHANGELOG conflict by keeping both Unreleased entries. The token coalescer source and regression test files are unchanged from 2b2f9d5, which passed all six actual iOS TokenRefreshCoalescerTests in run37095537416/job111124572876. The previous native component evidence is reused; no claim of a post-merge native run. GitHub now reports this PR MERGEABLE.

@paulb777 paulb777 added this to the 13.1.0 - M188 milestone Oct 3, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants