guarantee the read-write operation for cache token is atomic

This commit is contained in:
Wenkai Yin 2016-05-13 16:09:43 +08:00
parent 3ff3128921
commit 4a823facad
1 changed files with 22 additions and 6 deletions

View File

@ -22,6 +22,7 @@ import (
"net/http"
"net/url"
"strings"
"sync"
"time"
token_util "github.com/vmware/harbor/service/token"
@ -48,6 +49,7 @@ type tokenHandler struct {
cache string // cached token
expiresIn int // The duration in seconds since the token was issued that it will remain valid
issuedAt *time.Time // The RFC3339-serialized UTC standard time at which a given token was issued
sync.Mutex
}
// Scheme returns the scheme that the handler can handle
@ -77,8 +79,10 @@ func (t *tokenHandler) AuthorizeRequest(req *http.Request, params map[string]str
expired := true
if t.expiresIn != 0 && t.issuedAt != nil {
expired = t.issuedAt.Add(time.Duration(t.expiresIn) * time.Second).Before(time.Now().UTC())
cachedToken, cachedExpiredIn, cachedIssuedAt := t.getCachedToken()
if len(cachedToken) != 0 && cachedExpiredIn != 0 && cachedIssuedAt != nil {
expired = cachedIssuedAt.Add(time.Duration(cachedExpiredIn) * time.Second).Before(time.Now().UTC())
}
if expired || hasFrom {
@ -93,13 +97,11 @@ func (t *tokenHandler) AuthorizeRequest(req *http.Request, params map[string]str
token = to
if !hasFrom {
t.cache = token
t.expiresIn = expiresIn
t.issuedAt = issuedAt
t.updateCachedToken(to, expiresIn, issuedAt)
log.Debug("add token to cache")
}
} else {
token = t.cache
token = cachedToken
log.Debug("get token from cache")
}
@ -109,6 +111,20 @@ func (t *tokenHandler) AuthorizeRequest(req *http.Request, params map[string]str
return nil
}
func (t *tokenHandler) getCachedToken() (string, int, *time.Time) {
t.Lock()
defer t.Unlock()
return t.cache, t.expiresIn, t.issuedAt
}
func (t *tokenHandler) updateCachedToken(token string, expiresIn int, issuedAt *time.Time) {
t.Lock()
defer t.Unlock()
t.cache = token
t.expiresIn = expiresIn
t.issuedAt = issuedAt
}
// Implements interface Handler
type standardTokenHandler struct {
tokenHandler