ac.AuthToken = ""
return &cachingPermChecker{
Client: &ac,
- cache: make(map[string]time.Time),
+ cache: make(map[string]cacheEnt),
maxCurrent: 16,
}
}
+type cacheEnt struct {
+ time.Time
+ allowed bool
+}
+
type cachingPermChecker struct {
*arvados.Client
- cache map[string]time.Time
+ cache map[string]cacheEnt
maxCurrent int
}
func (pc *cachingPermChecker) Check(uuid string) (bool, error) {
pc.tidy()
- if t, ok := pc.cache[uuid]; ok && time.Now().Sub(t) < maxPermCacheAge {
- debugLogf("perm ok (cached): %+q %+q", pc.Client.AuthToken, uuid)
- return true, nil
+ now := time.Now()
+ if perm, ok := pc.cache[uuid]; ok && now.Sub(perm.Time) < maxPermCacheAge {
+ debugLogf("perm (cached): %+q %+q ...%v", pc.Client.AuthToken, uuid, perm.allowed)
+ return perm.allowed, nil
}
var buf map[string]interface{}
path, err := pc.PathForUUID("get", uuid)
err = pc.RequestAndDecode(&buf, "GET", path, nil, url.Values{
"select": {`["uuid"]`},
})
- if err, ok := err.(arvados.TransactionError); ok && err.StatusCode == http.StatusNotFound {
- debugLogf("perm err: %+q %+q: %s", pc.Client.AuthToken, uuid, err)
- return false, nil
- }
- if err != nil {
- debugLogf("perm !ok: %+q %+q", pc.Client.AuthToken, uuid)
+
+ var allowed bool
+ if err == nil {
+ allowed = true
+ } else if txErr, ok := err.(arvados.TransactionError); ok && txErr.StatusCode == http.StatusNotFound {
+ allowed = false
+ } else {
+ errorLogf("perm err: %+q %+q: %T %s", pc.Client.AuthToken, uuid, err, err)
return false, err
}
- debugLogf("perm ok: %+q %+q", pc.Client.AuthToken, uuid)
- pc.cache[uuid] = time.Now()
- return true, nil
+ debugLogf("perm: %+q %+q ...%v", pc.Client.AuthToken, uuid, allowed)
+ pc.cache[uuid] = cacheEnt{Time: now, allowed: allowed}
+ return allowed, nil
}
func (pc *cachingPermChecker) tidy() {