@@ -6,10 +6,12 @@ import (
66 "fmt"
77 "path"
88 "strings"
9+ "sync"
910 "time"
1011
1112 "github.com/cozy/cozy-stack/pkg/assets/model"
1213 "github.com/cozy/cozy-stack/pkg/config/config"
14+ "github.com/hashicorp/golang-lru/v2/expirable"
1315 "github.com/ncw/swift/v2"
1416)
1517
@@ -24,8 +26,19 @@ type SwiftFS struct {
2426 ctx context.Context
2527}
2628
29+ type cacheEntry struct {
30+ found bool
31+ content []byte
32+ }
33+
34+ var cache * expirable.LRU [string , cacheEntry ]
35+ var initCacheOnce sync.Once
36+
2737// NewSwiftFS instantiate a new SwiftFS.
2838func NewSwiftFS () (* SwiftFS , error ) {
39+ initCacheOnce .Do (func () {
40+ cache = expirable .NewLRU [string , cacheEntry ](1024 , nil , 1 * time .Hour )
41+ })
2942 ctx := context .Background ()
3043 swiftFS := & SwiftFS {swiftConn : config .GetSwiftConnection (), ctx : ctx }
3144 err := swiftFS .swiftConn .ContainerCreate (ctx , DynamicAssetsContainerName , nil )
@@ -54,14 +67,25 @@ func (s *SwiftFS) Add(context, name string, asset *model.Asset) error {
5467
5568func (s * SwiftFS ) Get (context , name string ) ([]byte , error ) {
5669 objectName := path .Join (context , name )
57- assetContent := new (bytes.Buffer )
70+ if entry , ok := cache .Get (objectName ); ok {
71+ if ! entry .found {
72+ return nil , swift .ObjectNotFound
73+ }
74+ return entry .content , nil
75+ }
5876
77+ assetContent := new (bytes.Buffer )
5978 _ , err := s .swiftConn .ObjectGet (s .ctx , DynamicAssetsContainerName , objectName , assetContent , true , nil )
6079 if err != nil {
80+ if err == swift .ObjectNotFound {
81+ cache .Add (objectName , cacheEntry {found : false })
82+ }
6183 return nil , err
6284 }
6385
64- return assetContent .Bytes (), nil
86+ content := assetContent .Bytes ()
87+ cache .Add (objectName , cacheEntry {found : true , content : content })
88+ return content , nil
6589}
6690
6791func (s * SwiftFS ) Remove (context , name string ) error {
0 commit comments