diff options
author | pg9182 <96569817+pg9182@users.noreply.github.com> | 2022-10-14 15:07:49 -0400 |
---|---|---|
committer | pg9182 <96569817+pg9182@users.noreply.github.com> | 2022-10-14 15:07:49 -0400 |
commit | 529e7d2f30b7457d069d00cefdb9a36aa1c5fd71 (patch) | |
tree | 30c1eb17d88661a1048c3b9e9bab67d9995d834a | |
parent | 33a1bc3047de6a3f3184171a5e73abd2639bd261 (diff) | |
download | Atlas-529e7d2f30b7457d069d00cefdb9a36aa1c5fd71.tar.gz Atlas-529e7d2f30b7457d069d00cefdb9a36aa1c5fd71.zip |
pkg/origin: Implement backoff for AuthMgr
-rw-r--r-- | pkg/origin/authmgr.go | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/pkg/origin/authmgr.go b/pkg/origin/authmgr.go index bd2f14e..8fde216 100644 --- a/pkg/origin/authmgr.go +++ b/pkg/origin/authmgr.go @@ -8,6 +8,8 @@ import ( "time" ) +var ErrAuthMgrBackoff = errors.New("not refreshing token due to backoff") + // AuthMgr manages Origin NucleusTokens. It is efficient and safe for concurrent // use. // @@ -27,10 +29,17 @@ type AuthMgr struct { // SID. Credentials func() (email, password string, err error) - authMu sync.Mutex // guards authWg so only one goroutine can get it - authWg sync.WaitGroup // guards auth/authErr and allows waiting for updates - authErr error // stores the last auth error - auth AuthState // stores the current auth tokens + // Backoff, if provided, checks if another refresh is allowed after a + // failure. If it returns false, ErrAuthMgrBackoff will be returned + // immediately from OriginAuth. + Backoff func(err error, time time.Time, count int) bool + + authMu sync.Mutex // guards authWg so only one goroutine can get it + authWg sync.WaitGroup // guards the variables below and allows waiting for updates + authErr error // last auth error + authErrTime time.Time // last auth error time + authErrCount int // consecutive auth errors + auth AuthState // current auth tokens } // AuthState contains the current authentication tokens. @@ -81,6 +90,11 @@ func (a *AuthMgr) OriginAuth(refresh bool) (NucleusToken, bool, error) { // another goroutine is refreshing return a.OriginAuth(false) } + if a.authErr != nil && a.Backoff != nil { + if !a.Backoff(a.authErr, a.authErrTime, a.authErrCount) { + return a.auth.NucleusToken, true, fmt.Errorf("%w (%d attempts, last error: %v)", ErrAuthMgrBackoff, a.authErrCount, a.authErrCount) + } + } a.authErr = func() (err error) { defer func() { if p := recover(); p != nil { @@ -129,6 +143,16 @@ func (a *AuthMgr) OriginAuth(refresh bool) (NucleusToken, bool, error) { } return }() + if a.authErrCount != 0 { + a.authErr = fmt.Errorf("%w (attempt %d)", a.authErr, a.authErrCount) + } + if a.authErr != nil { + a.authErrCount++ + a.authErrTime = time.Now() + } else { + a.authErrCount = 0 + a.authErrTime = time.Time{} + } if a.Updated != nil { go a.Updated(a.auth, a.authErr) } |