type cache struct {
TTL arvados.Duration
+ UUIDTTL arvados.Duration
MaxCollectionEntries int
MaxCollectionBytes int64
MaxPermissionEntries int
}
}
+// Update saves a modified version (fs) to an existing collection
+// (coll) and, if successful, updates the relevant cache entries so
+// subsequent calls to Get() reflect the modifications.
+func (c *cache) Update(client *arvados.Client, coll arvados.Collection, fs arvados.CollectionFileSystem) error {
+ c.setupOnce.Do(c.setup)
+
+ if m, err := fs.MarshalManifest("."); err != nil || m == coll.ManifestText {
+ return err
+ } else {
+ coll.ManifestText = m
+ }
+ var updated arvados.Collection
+ defer c.pdhs.Remove(coll.UUID)
+ err := client.RequestAndDecode(&updated, "PATCH", "/arvados/v1/collections/"+coll.UUID, client.UpdateBody(coll), nil)
+ if err == nil {
+ c.collections.Add(client.AuthToken+"\000"+coll.PortableDataHash, &cachedCollection{
+ expire: time.Now().Add(time.Duration(c.TTL)),
+ collection: &updated,
+ })
+ }
+ return err
+}
+
func (c *cache) Get(arv *arvadosclient.ArvadosClient, targetID string, forceReload bool) (*arvados.Collection, error) {
c.setupOnce.Do(c.setup)
var collection *arvados.Collection
if pdh != "" {
- collection = c.lookupCollection(pdh)
+ collection = c.lookupCollection(arv.ApiToken + "\000" + pdh)
}
if collection != nil && permOK {
return nil, err
}
if current.PortableDataHash == pdh {
- exp := time.Now().Add(time.Duration(c.TTL))
c.permissions.Add(permKey, &cachedPermission{
- expire: exp,
+ expire: time.Now().Add(time.Duration(c.TTL)),
})
if pdh != targetID {
c.pdhs.Add(targetID, &cachedPDH{
- expire: exp,
+ expire: time.Now().Add(time.Duration(c.UUIDTTL)),
pdh: pdh,
})
}
// PDH changed, but now we know we have
// permission -- and maybe we already have the
// new PDH in the cache.
- if coll := c.lookupCollection(current.PortableDataHash); coll != nil {
+ if coll := c.lookupCollection(arv.ApiToken + "\000" + current.PortableDataHash); coll != nil {
return coll, nil
}
}
expire: exp,
})
c.pdhs.Add(targetID, &cachedPDH{
- expire: exp,
+ expire: time.Now().Add(time.Duration(c.UUIDTTL)),
pdh: collection.PortableDataHash,
})
- // Disabled, see #11945
- // c.collections.Add(collection.PortableDataHash, &cachedCollection{
- // expire: exp,
- // collection: collection,
- // })
- // if int64(len(collection.ManifestText)) > c.MaxCollectionBytes/int64(c.MaxCollectionEntries) {
- // go c.pruneCollections()
- // }
+ c.collections.Add(arv.ApiToken+"\000"+collection.PortableDataHash, &cachedCollection{
+ expire: exp,
+ collection: collection,
+ })
+ if int64(len(collection.ManifestText)) > c.MaxCollectionBytes/int64(c.MaxCollectionEntries) {
+ go c.pruneCollections()
+ }
return collection, nil
}
return size
}
-func (c *cache) lookupCollection(pdh string) *arvados.Collection {
- if pdh == "" {
- return nil
- } else if ent, cached := c.collections.Get(pdh); !cached {
+func (c *cache) lookupCollection(key string) *arvados.Collection {
+ if ent, cached := c.collections.Get(key); !cached {
return nil
} else {
ent := ent.(*cachedCollection)
if ent.expire.Before(time.Now()) {
- c.collections.Remove(pdh)
+ c.collections.Remove(key)
return nil
} else {
atomic.AddUint64(&c.stats.CollectionHits, 1)