-
Notifications
You must be signed in to change notification settings - Fork 18
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
add TokenFetcher struct for automatic token refresh #13
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adelbertc thank you for a speedy PR :), it looks really great.
I have a few suggestions, would like to get your take on them :)
- Could we make
TokenFetcher.refresh_buffer
Option<Duration>
, and have a default ofDuration::new(0, 0)
. That wayTokenFetcher::new()
would have a simpler. signature, and you could add aTokenFetcher::new_with_refresh_buffer()
to allow for setting therefresh_buffer
. - I really like the
TokenFetcher
abstraction, it would be great if you could also update theREADME
so that the snippet there showsTokenFetcher
fetch
andrefresh
functionality. - Ideally you'd also add a
blocking
version offetch_token
, that way we could slowly deprecateget_token_*
calls in favour ofTokenFetcher
@durch Thanks for the quick review! I've added some docs to the README, here are my thoughts on the other two bits of feedback:
I like this idea of having a cleaner signature but ran into two issues:
I started doing this too before realizing we need to provide a |
Just realized for that latter point if we go to |
@adelbertc great stuff :) On the multiple constructors, I agree its not very ergonomic, so probably better to leave it more configurable. More importantly the point you make around refresh races is excellent, better to have it be explicitly set, at the expens of a few lines of code mode. As for the All in all thank you for this great contribution |
Published to crates.io as |
Closes #12 .
get_token_with_client
variant that allows clients to pass in their ownreqwest::Client
get_token
(and thereforeget_token_blocking
and friends) to call intoget_token_with_client
TokenFetcher
struct that will automatically refresh the token for eachfetch_token
callget_token_with_client
. What I decided to do instead is to allow clients to specify arefresh_buffer
and for eachfetch_token
request check "isnow()
>= + ( - <refresh_buffer>)"? If so, refresh.EDIT: Figured out how to get tests in!
EDIT 2: I switched from using a mutable field to using
arc_swap::ArcSwap
since token refresh seems to be a perfect use case for that (often read, seldom updated). However this does incur anarc-swap
dependency.. I can put this behind a feature flag if you don't want to incur this dependency, just LMK!One open question for this PR is there is some slightly non-trivial logic here with when we decide to refresh or not refresh which I would like to test ideally. Doing so in the current design would require being able to hijack theToken
response from the HTTP class so we can shove in customexpires_in
values and see what happens. Anecdotally I have used the mockito library, but only in contexts where I require clients to pass in a URL explicitly anyways so it is easy to pass inmockito::server_url()
just in the tests and keepmockito
as adev-dependencies
. In this case since the URL is dictated on the user side we would need to do the trick they mention in the docs with something like:But this would require incurring a mockito dependency on all users which seems.. strange. Curious to get your take on this.