Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort out token refresh and saving synchronization II #102

Conversation

michpohl
Copy link
Contributor

@michpohl michpohl commented Sep 10, 2024

This PR adds a NetworkingJobHandler which can be used to cancel token refresh calls.

This is needed e.g. when calling setCredentials, as otherwise a call to getCredentials that was issued before, but returns after this operation can overwrite and erase the credentials just set.

This is an alternative approach to solving the same problem #101 addresses.

@michpohl michpohl changed the title Michael/sort out token refresh and saving synchronization ii Sort out token refresh and saving synchronization ii Sep 10, 2024
@michpohl michpohl changed the title Sort out token refresh and saving synchronization ii Sort out token refresh and saving synchronization II Sep 10, 2024
Now that we define the scope externally, this is needed so tests can properly control these coroutines
@michpohl michpohl force-pushed the michael/Sort-out-token-refresh-and-saving-synchronization-II branch from 855cd98 to b252da8 Compare September 11, 2024 05:41
@michpohl michpohl marked this pull request as ready for review September 11, 2024 07:40
@michpohl michpohl requested a review from a team as a code owner September 11, 2024 07:40
@michpohl michpohl requested review from subhasha1 and removed request for subhasha1 September 11, 2024 07:40
@@ -78,6 +80,7 @@ internal class LoginRepository constructor(
}

suspend fun setCredentials(credentials: Credentials, refreshToken: String? = null) {
networkingJobHandler.cancelAllJobs()
Copy link
Member

Choose a reason for hiding this comment

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

I think there's a problem with this. You're going to cancel getCredentials jobs that have been added to the collection before getting here, yes. But that doesn't cover jobs that are added after this line is executed. Those will be capable of overwriting the credentials set by this method, even if the corresponding call to getCredentials happened before. You would need to run job cancellation within the mutex too I think, so that you achieve what my understanding of what you want is - have token retrieval and write run exclusively with each other. But that will give you a new problem - if there's a write request while ownership of the mutex is held by a retrieval request, it needs to bypass the wait by cancelling the existing ownership of the mutex. That may be tricky to achieve with this approach I think.

I think the easiest approach to do what you need is to rework concurrency management in the sdk to use Handler. It's a queue where you can send runnables. It's backed by a single thread, so it's thread-safe by default. You'll have two types of runnables - one for getCredentials and one for setCredentials. If you receive a request for setCredentials, you add the runnable to the end of the queue - if it's for setCredentials, you do removeCallbacks for your currently queued setCredentials Runnable if any, save the new Runnable as your current one so you can remove it later, and post it at the front of the queue so it runs before any other getCredentials requests.

Thoughts?

Copy link
Contributor Author

@michpohl michpohl Sep 11, 2024

Choose a reason for hiding this comment

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

Well, mainly I am trying to pragmatically present a solution for a specific issue that occurs only when using our "backdoor" setCredentials (and only when using during certain UI tests). Both my attempts solve the problem (I verified) without causing new issues elsewhere.

The other approach avoided the problems you suspect this one here has, by choosing a less "correct" approach than this here. For this edge case that is perfectly fine imho.

It's fine to disagree with my solutions though, and since you probably have had more exposure to coroutine concurrency management in the player, and appear you know how to solve this issue right, would you mind creating a proposal?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There also is the option to pick one solution, and creating a task to improve the situation in a more general approach, which might be the most pragmatic.

@michpohl michpohl closed this Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants