Skip to content

Commit 1d79b60

Browse files
fix: add mutex to handle concurrency in updating token
1 parent 3b9eba4 commit 1d79b60

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

go/rtl/auth.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"net/url"
1111
"os"
1212
"reflect"
13+
"sync"
1314
"time"
1415

1516
"golang.org/x/oauth2"
@@ -41,18 +42,36 @@ type AuthSession struct {
4142
Client http.Client
4243
token *oauth2.Token
4344
source oauth2.TokenSource
45+
mu sync.RWMutex
4446
}
4547

48+
const tokenLeeway = 10 * time.Second
49+
4650
func (s *AuthSession) IsActive() bool {
51+
s.mu.RLock()
52+
defer s.mu.RUnlock()
4753
if s.token == nil {
4854
return false
4955
}
50-
leeway := time.Second * 10
51-
return s.token.Expiry.After(time.Now().Add(leeway))
56+
return s.token.Expiry.After(time.Now().Add(tokenLeeway))
5257
}
5358

5459
func (s *AuthSession) Login() (*oauth2.Token, error) {
55-
if s.IsActive() {
60+
// First, check with a read lock to avoid contention if the token is valid.
61+
s.mu.RLock()
62+
if s.token != nil && s.token.Expiry.After(time.Now().Add(tokenLeeway)) {
63+
token := s.token
64+
s.mu.RUnlock()
65+
return token, nil
66+
}
67+
s.mu.RUnlock()
68+
69+
// If the token is invalid or nil, acquire a write lock to refresh it.
70+
s.mu.Lock()
71+
defer s.mu.Unlock()
72+
73+
// Re-check after obtaining the write lock, in case another goroutine refreshed it.
74+
if s.token != nil && s.token.Expiry.After(time.Now().Add(tokenLeeway)) {
5675
return s.token, nil
5776
}
5877

0 commit comments

Comments
 (0)