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

refactor(fresh_dio): replace Interceptor with QueuedInterceptor #68

Merged
merged 6 commits into from Jul 25, 2023

Conversation

SebastianKlaiber
Copy link
Contributor

@SebastianKlaiber SebastianKlaiber commented May 27, 2022

Interceptors are called concurrently, this could lead to a problem if multiple API calls are executed at the same time. Therefore, Queued Interceptor was introduced to solve this problem.

I also updated dio to version 4.0.6 because Queued Interceptor was introduced in version 4.0.2

From the Dio documentation:

QueuedInterceptor
Interceptor can be executed concurrently, that is, all of the requests enter the interceptor at once, rather than executing sequentially. However, in some cases we expect that requests enter the interceptor sequentially like #590 。 Therefore, we need to provide a mechanism for sequential access(one by one) to interceptors and QueuedInterceptor can solve this problem.

@vasilich6107
Copy link

Hi @felangel do you have any estimates on reviewing this PR?

@felangel
Copy link
Owner

Hi @felangel do you have any estimates on reviewing this PR?

sorry for the delay planning to test and publish today

@felangel felangel added the enhancement New feature or request label Jun 23, 2022
@felangel
Copy link
Owner

@vasilich6107 can you confirm whether the changes resolve the issue for you?

@SebastianKlaiber
Copy link
Contributor Author

You could test it by replacing

fresh_dio: ^0.3.2

with

fresh_dio: 
    git:
      url: https://github.com/SebastianKlaiber/fresh.git
      path: packages/fresh_dio

in your pubspec.yaml

@SebastianKlaiber
Copy link
Contributor Author

@felangel @vasilich6107 Is there anything else I can support? So that we can get on with the PR?

@felangel
Copy link
Owner

@felangel @vasilich6107 Is there anything else I can support? So that we can get on with the PR?

I was waiting for confirmation that the changes in the PR address the issue. @SebastianKlaiber can you confirm?

@SebastianKlaiber
Copy link
Contributor Author

I'll check the related issue #29 and follow the steps to reproduce.

@SebastianKlaiber
Copy link
Contributor Author

The refresh calls have definitely become less, but still too many. Maybe there is a way to clear the queue if the call was successful.

image
image

@SebastianKlaiber
Copy link
Contributor Author

Unfortunately, I could not find a way to clear all Queued Interceptors of a given type. Hopefully I have time to investigate a little more in this topic this week. Any suggestion from your side?

@vasilich6107
Copy link

@SebastianKlaiber thanks for help with testing
This is strange behaviour cause Queued Interceptors are supposed to wait in queue rather than being executed in parallel manner...

@SebastianKlaiber
Copy link
Contributor Author

I think we could solve the Issue if we add an JWT Decoder and check if the access token is a valid JWT and then check if the JWT is still valid. If the JWT is expired, then trigger the refresh callback. We could also add the validation function as a parameter, then the consumer of the library can specify when the access token is valid.

Or we create an issue on the Dio repository.

@felangel what is your opinion on this?

@Gaurav192
Copy link

@SebastianKlaiber @felangel Can we check if current token is same compared to token in request headers? In case current token is different then return it instead of calling refresh token.

@SebastianKlaiber
Copy link
Contributor Author

@Gaurav192 thanks for helping out. I was busy the last time, releasing a new version of my app. I will check your changes today.

@SebastianKlaiber
Copy link
Contributor Author

Unfortunately, we still have too many refresh calls here as well.

Screenshot 2022-09-01 at 11 06 06

@Gaurav192
Copy link

Unfortunately, we still have too many refresh calls here as well.

Screenshot 2022-09-01 at 11 06 06

Just to make sure, are you using default values in repo and url: https://github.com/Gaurav192/fresh.git in pubspec?

@SebastianKlaiber
Copy link
Contributor Author

I checked out your repo and changed the version to the local path in the pubspec.yaml. I added a breakpoint and isEqual returns always true.

@lalit3102
Copy link

Hi,
I am also facing this issue, when this PR is going to merge?

@felangel
Copy link
Owner

Hi,
I am also facing this issue, when this PR is going to merge?

I’ll try to take a look this weekend apologies for the delay

@SebastianKlaiber
Copy link
Contributor Author

@felangel if you have a suggestion, I'm happy to help further with the implementation, just currently not sure what direction the implementation should go in.

Provide some validation logic or do some header checks.

@kuhnroyal
Copy link

This can be picked up again after the dio 5.0.0 merge.
There might have been some changes and if not, then we need to possibly adjust on the dio side.

@felangel
Copy link
Owner

@SebastianKlaiber just resolved merge conflicts and pulled in dio 5.0.0 can you please re-test when you have a chance? Thanks!

@SebastianKlaiber
Copy link
Contributor Author

Thanks. Hopefully I've some time this afternoon.

@SebastianKlaiber
Copy link
Contributor Author

SebastianKlaiber commented Mar 29, 2023

Still the same issue with the cookie example, https://github.com/artflutter/fresh_repro.

I did some more investigation:
If the refresh handling is not delayed, then I seem to work as expected.

final response = await authRestClient.refreshToken(refreshToken: refreshToken);

return OAuth2Token(
  accessToken: response.token,
  refreshToken: response.refreshToken,
);

But If I add some delay, then I get too much refresh calls.

return await Future.delayed(const Duration(milliseconds: 500), () async {
  final response = await authRestClient.refreshToken(refreshToken: refreshToken);

  return OAuth2Token(
    accessToken: response.token,
    refreshToken: response.refreshToken,
  );
});

The new version is using a shelf API with bearer auth from this repository. https://github.com/graphicbeacon/dart_spa_boilerplate

Copy link
Owner

@felangel felangel left a comment

Choose a reason for hiding this comment

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

LGTM ✅

@felangel felangel merged commit 1f26a53 into felangel:master Jul 25, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants