Commit f06f6858 authored by Kirill Smelkov's avatar Kirill Smelkov

X works with go -race under wrk load

parent caaf8192
...@@ -36,6 +36,9 @@ type AuthCacheEntry struct { ...@@ -36,6 +36,9 @@ type AuthCacheEntry struct {
// FIXME we need to lock the entry only to "correctly" update Nhit on // FIXME we need to lock the entry only to "correctly" update Nhit on
// read side but we can tolerate some looses in Nhit and update it // read side but we can tolerate some looses in Nhit and update it
// without mutex or atomic. Only -race complains... // without mutex or atomic. Only -race complains...
// (we could use atomic.Value for atomic cache entry updates from
// refresher withot need for locks on readers side, but the need to do
// .Nhit++ on readers side ruins that)
sync.Mutex sync.Mutex
AuthReply AuthReply
...@@ -55,10 +58,12 @@ type AuthCache struct { ...@@ -55,10 +58,12 @@ type AuthCache struct {
cached map[string]*AuthCacheEntry cached map[string]*AuthCacheEntry
} }
var authCache = AuthCache{} // XXX make map ? var authCache = AuthCache{cached: make(map[string]*AuthCacheEntry)}
// XXX u should not be in args? // XXX u should not be in args?
func (c *AuthCache) VerifyDownloadAccess(u *upstream, project string) AuthReply { func (c *AuthCache) VerifyDownloadAccess(u *upstream, project string) AuthReply {
var authReply AuthReply
// first try to read from cache in parallel with other readers // first try to read from cache in parallel with other readers
c.mu.RLock() c.mu.RLock()
auth := c.cached[project] auth := c.cached[project]
...@@ -67,7 +72,6 @@ func (c *AuthCache) VerifyDownloadAccess(u *upstream, project string) AuthReply ...@@ -67,7 +72,6 @@ func (c *AuthCache) VerifyDownloadAccess(u *upstream, project string) AuthReply
have_entry: have_entry:
// entry in cache - use it // entry in cache - use it
if auth != nil { if auth != nil {
//have_entry:
<-auth.ready // make sure it is ready <-auth.ready // make sure it is ready
auth.Lock() auth.Lock()
...@@ -76,6 +80,7 @@ have_entry: ...@@ -76,6 +80,7 @@ have_entry:
// project, // project,
// time.Since(time.Unix(auth.Tauth, 0)), // time.Since(time.Unix(auth.Tauth, 0)),
// auth.Nhit) // auth.Nhit)
authReply = auth.AuthReply
auth.Unlock() auth.Unlock()
// no entry - relock the cache in exclusive mode, create empty entry, // no entry - relock the cache in exclusive mode, create empty entry,
...@@ -100,6 +105,8 @@ have_entry: ...@@ -100,6 +105,8 @@ have_entry:
auth.Tauth = time.Now().Unix() auth.Tauth = time.Now().Unix()
auth.Nhit = 0 auth.Nhit = 0
authReply = auth.AuthReply
// broadcast to other goroutines this entry is ready // broadcast to other goroutines this entry is ready
close(auth.ready) close(auth.ready)
...@@ -107,12 +114,12 @@ have_entry: ...@@ -107,12 +114,12 @@ have_entry:
go c.refreshEntry(auth, u, project) go c.refreshEntry(auth, u, project)
} }
return auth.AuthReply return authReply
} }
// Time period for refreshing / removing unused entires in authCache // Time period for refreshing / removing unused entires in authCache
const authCacheRefresh = 10 * time.Second // XXX 30 const authCacheRefresh = 5 * time.Second // XXX 30
// Goroutine to refresh auth cache entry periodically while it is used. // Goroutine to refresh auth cache entry periodically while it is used.
// if the entry is detected to be not used - remove it from cache and stop refreshing. // if the entry is detected to be not used - remove it from cache and stop refreshing.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment