Proposal on how to fix issue #692#1002
Proposal on how to fix issue #692#1002johanblumenberg wants to merge 1 commit intogoogleapis:mainfrom truid-app:fix-issue-692
Conversation
|
🤖 I detect that the PR title and the commit message differ and there's only one commit. To use the PR title for the commit history, you can use Github's automerge feature with squashing, or use -- conventional-commit-lint bot |
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
| public OAuthValue call() throws Exception { | ||
| return OAuthValue.create(refreshAccessToken(), getAdditionalHeaders()); | ||
| OAuthValue result = OAuthValue.create(refreshAccessToken(), getAdditionalHeaders()); | ||
|
|
There was a problem hiding this comment.
Would it be better to move finishRefreshAsync up onto this line?
There was a problem hiding this comment.
Yes, that might be better.
I don't know if there is any listener that relies on the task being completed, so I didn't want to change it.
|
LGTM, do you mind signing the CLA and updating to a conventional commit? |
| return OAuthValue.create(refreshAccessToken(), getAdditionalHeaders()); | ||
| OAuthValue result = OAuthValue.create(refreshAccessToken(), getAdditionalHeaders()); | ||
|
|
||
| synchronized (lock) { |
There was a problem hiding this comment.
Is this lock necessary? Only one thread should be doing work on this future right?
There was a problem hiding this comment.
The lock was taken in the finishRefreshAsync() method when modifying the value variable. I wasn't sure why, if it was needed to protect the value variable or something else. But you are probably right, the lock is not necessary here.
But don't take my word for it ... :)
|
There are a few test regressions introduced by this. Hopefully @igorbernstein2 can chime in on those |
|
Thanks @johanblumenberg for the fix. We are eager to get this merged so I have forked your PR here #1031 in order to resolve the test failures. I will make sure you are credited if that is the PR that lands. |
@clundin25 Perfect, thanks a lot |
|
Thanks for suggestion, closing as we are about to fix with another PR: #1031 |
Questionnaire
Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
Fixes #692
Problem
There is a race condition here
google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
Line 252 in 429b481
When
taskis completed, two things happen:value:google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
Line 261 in 429b481
google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
Line 181 in 429b481
When more than one thread is involved, there is a race condition in which of these that get to execute first. Most of the time the listener executes first, and everything works. But now and then the listener is delayed, and that means that whoever is waiting for
refresh()to complete will read the old token.Logs
Adding a sleep in the listener shows that the race condition exists: https://github.com/veritru/google-auth-library-java/commit/551513b233339b952ec40366e12d448e8c7f7661
This produces the following logs:
The "refresh() done" log is the point where the caller would get and use the access token. It does not wait for the listener to actually update the current access token.
Solution Proposal
The proposed solution is to move the update of
valueto be done before the task is completed.