oauthuil: implement a timer for token expiry

This commit is contained in:
Nick Craig-Wood 2016-08-08 19:02:27 +01:00
parent 4f9e805d44
commit 23d8ba41d5

View file

@ -114,6 +114,7 @@ type TokenSource struct {
token *oauth2.Token token *oauth2.Token
config *oauth2.Config config *oauth2.Config
ctx context.Context ctx context.Context
expiryTimer *time.Timer // signals whenever the token expires
} }
// Token returns a token or an error. // Token returns a token or an error.
@ -137,6 +138,10 @@ func (ts *TokenSource) Token() (*oauth2.Token, error) {
changed := *token != *ts.token changed := *token != *ts.token
ts.token = token ts.token = token
if changed { if changed {
// Bump on the expiry timer if it is set
if ts.expiryTimer != nil {
ts.expiryTimer.Reset(ts.timeToExpiry())
}
err = putToken(ts.name, token) err = putToken(ts.name, token)
if err != nil { if err != nil {
return nil, err return nil, err
@ -152,6 +157,32 @@ func (ts *TokenSource) Invalidate() {
ts.mu.Unlock() ts.mu.Unlock()
} }
// timeToExpiry returns how long until the token expires
//
// Call with the lock held
func (ts *TokenSource) timeToExpiry() time.Duration {
t := ts.token
if t == nil {
return 0
}
if t.Expiry.IsZero() {
return 3E9 * time.Second // ~95 years
}
return t.Expiry.Sub(time.Now())
}
// OnExpiry returns a channel which has the time written to it when
// the token expires. Note that there is only one channel so if
// attaching multiple go routines it will only signal to one of them.
func (ts *TokenSource) OnExpiry() <-chan time.Time {
ts.mu.Lock()
defer ts.mu.Unlock()
if ts.expiryTimer == nil {
ts.expiryTimer = time.NewTimer(ts.timeToExpiry())
}
return ts.expiryTimer.C
}
// Check interface satisfied // Check interface satisfied
var _ oauth2.TokenSource = (*TokenSource)(nil) var _ oauth2.TokenSource = (*TokenSource)(nil)