Skip to content

Commit 51dab12

Browse files
committed
better duration calculation:
1 parent 906e4c4 commit 51dab12

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

token_manager.go

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,19 @@ type TokenManagerOptions struct {
1818
// ExpirationRefreshRatio is the ratio of the token expiration time to refresh the token.
1919
// It is used to determine when to refresh the token.
2020
// The value should be between 0 and 1.
21-
// For example, if the expiration time is 1 hour and the ratio is 0.5,
22-
// the token will be refreshed after 30 minutes.
21+
// For example, if the expiration time is 1 hour and the ratio is 0.75,
22+
// the token will be refreshed after 45 minutes. (the token is refreshed when 75% of its lifetime has passed)
2323
//
2424
// default: 0.7
2525
ExpirationRefreshRatio float64
2626

2727
// LowerRefreshBoundMs is the lower bound for the refresh time in milliseconds.
28-
// It is used to determine when to refresh the token.
29-
// The value should be greater than 0.
30-
// For example, if the expiration time is 1 hour and the lower bound is 30 minutes,
31-
// the token will be refreshed after 30 minutes.
28+
// Represents the minimum time in milliseconds before token expiration to trigger a refresh, in milliseconds.
29+
// This value sets a fixed lower bound for when a token refresh should occur, regardless
30+
// of the token's total lifetime.
3231
//
3332
// default: 0 ms (no lower bound, refresh based on ExpirationRefreshRatio)
34-
LowerRefreshBoundMs int
33+
LowerRefreshBoundMs int64
3534

3635
// IdentityProviderResponseParser is a function that parses the IdentityProviderResponse.
3736
// The function takes the response and based on its type returns the populated Token object.
@@ -168,17 +167,24 @@ func NewTokenManager(idp IdentityProvider, options TokenManagerOptions) (TokenMa
168167
token: nil,
169168
closed: make(chan struct{}),
170169
expirationRefreshRatio: options.ExpirationRefreshRatio,
170+
lowerRefreshBoundMs: options.LowerRefreshBoundMs,
171+
lowerBoundDuration: time.Duration(options.LowerRefreshBoundMs) * time.Millisecond,
171172
identityProviderResponseParser: options.IdentityProviderResponseParser,
172173
retryOptions: options.RetryOptions,
173174
}, nil
174175
}
175176

176177
// entraidTokenManager is a struct that implements the TokenManager interface.
177178
type entraidTokenManager struct {
178-
idp IdentityProvider
179+
// idp is the identity provider used to obtain the token.
180+
idp IdentityProvider
181+
182+
// token is the authentication token for the user which should be kept in memory if valid.
179183
token *Token
180184

181-
// TokenParser is a function that parses the token.
185+
// identityProviderResponseParser is a function that parses the IdentityProviderResponse.
186+
// it can be supplied by the user to parse the token and return the populated Token object or
187+
// the default implementation will be used.
182188
identityProviderResponseParser IdentityProviderResponseParserFunc
183189

184190
// retryOptions is a struct that contains the options for retrying the token request.
@@ -199,8 +205,22 @@ type entraidTokenManager struct {
199205

200206
// expirationRefreshRatio is the ratio of the token expiration time to refresh the token.
201207
// It is used to determine when to refresh the token.
208+
// The value should be between 0 and 1.
209+
// For example, if the expiration time is 1 hour and the ratio is 0.75,
210+
// the token will be refreshed after 45 minutes. (the token is refreshed when 75% of its lifetime has passed)
202211
expirationRefreshRatio float64
203212

213+
// lowerRefreshBoundMs is the lower bound for the refresh time in milliseconds.
214+
// Represents the minimum time in milliseconds before token expiration to trigger a refresh, in milliseconds.
215+
// This value sets a fixed lower bound for when a token refresh should occur, regardless
216+
// of the token's total lifetime.
217+
lowerRefreshBoundMs int64
218+
219+
// lowerBoundDuration is the lower bound for the refresh time in time.Duration.
220+
lowerBoundDuration time.Duration
221+
222+
// closed is a channel that is closed when the token manager is closed.
223+
// It is used to signal the token manager to stop requesting tokens.
204224
closed chan struct{}
205225
}
206226

@@ -238,6 +258,19 @@ type TokenListener interface {
238258
OnTokenError(err error)
239259
}
240260

261+
func (e *entraidTokenManager) durationToRenewal() time.Duration {
262+
if e.token == nil {
263+
return 0
264+
}
265+
// Calculate the time to renew the token based on the expiration refresh ratio
266+
duration := time.Duration(float64(time.Until(e.token.expiresOn)) * e.expirationRefreshRatio)
267+
if duration < e.lowerBoundDuration {
268+
return e.lowerBoundDuration
269+
}
270+
271+
return duration
272+
}
273+
241274
// Start starts the token manager and returns cancelFunc to stop the token manager.
242275
// It takes a TokenListener as an argument, which is used to receive updates.
243276
// The token manager will call the listener's OnTokenNext method with the updated token.
@@ -265,7 +298,7 @@ func (e *entraidTokenManager) Start(listener TokenListener) (cancelFunc, error)
265298
case <-e.closed:
266299
// Token manager is closed, stop the loop
267300
return
268-
case <-time.After(time.Until(token.expiresOn) * time.Duration(e.expirationRefreshRatio)):
301+
case <-time.After(e.durationToRenewal()):
269302
// Token is about to expire, refresh it
270303
for i := 0; i < e.retryOptions.MaxAttempts; i++ {
271304
select {

0 commit comments

Comments
 (0)