Skip to content

Commit d36a3bd

Browse files
authored
[registry] Fix token refresh firing every 20s instead of near expiry (#21)
The refresh_interval variable was set to expires_in - 20 after each refresh, then used in the check `now + refresh_interval >= expired_at`. Since expired_at = fetch_time + expires_in, this resolved to "refresh when 20s have passed since last fetch" rather than "refresh 20s before expiry". Replace the mutable refresh_interval with a fixed margin constant so the check correctly triggers only when the token is about to expire within the next 20 seconds.
1 parent f243560 commit d36a3bd

1 file changed

Lines changed: 6 additions & 12 deletions

File tree

storage/src/backend/registry.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ const HEADER_WWW_AUTHENTICATE: &str = "www-authenticate";
3333

3434
const REGISTRY_DEFAULT_TOKEN_EXPIRATION: u64 = 10 * 60; // in seconds
3535
const REGISTRY_CONFIG_POLL_INTERVAL: u64 = 5; // in seconds
36+
// Refresh tokens this many seconds before they expire to avoid using an expired token.
37+
const REGISTRY_TOKEN_REFRESH_MARGIN: u64 = 20; // in seconds
3638

3739
/// Error codes related to registry storage backend operations.
3840
#[derive(Debug)]
@@ -1012,18 +1014,17 @@ impl Registry {
10121014
fn start_refresh_token_thread(&self) {
10131015
let conn = self.connection.clone();
10141016
let state = self.state.clone();
1015-
// FIXME: we'd better allow users to specify the expiration time.
1016-
let mut refresh_interval = REGISTRY_DEFAULT_TOKEN_EXPIRATION;
10171017
thread::spawn(move || {
10181018
loop {
10191019
// Check for config auth changes every tick.
10201020
state.refresh_cached_auth_from_config(&conn);
10211021

10221022
if let Ok(now_timestamp) = SystemTime::now().duration_since(UNIX_EPOCH) {
10231023
if let Some(token_expired_at) = state.token_expired_at.load().as_deref() {
1024-
// If the token will expire within the next refresh interval,
1025-
// refresh it immediately.
1026-
if now_timestamp.as_secs() + refresh_interval >= *token_expired_at {
1024+
// Refresh the token if it will expire within the margin.
1025+
if now_timestamp.as_secs() + REGISTRY_TOKEN_REFRESH_MARGIN
1026+
>= *token_expired_at
1027+
{
10271028
if let Some(cached_bearer_auth) =
10281029
state.cached_bearer_auth.load().as_deref()
10291030
{
@@ -1034,16 +1035,9 @@ impl Registry {
10341035
debug!(
10351036
"[refresh_token_thread] registry token has been refreshed"
10361037
);
1037-
// Refresh cached token.
10381038
state
10391039
.cached_auth
10401040
.set(&state.cached_auth.get(), new_cached_auth);
1041-
// Reset refresh interval according to real expiration time,
1042-
// and advance 20s to handle the unexpected cases.
1043-
refresh_interval = token
1044-
.expires_in
1045-
.checked_sub(20)
1046-
.unwrap_or(token.expires_in);
10471041
} else {
10481042
error!(
10491043
"[refresh_token_thread] failed to refresh registry token"

0 commit comments

Comments
 (0)