Skip to content

Commit 1b80e63

Browse files
committed
WIP to implement shares caching into the gateway
1 parent ee10143 commit 1b80e63

File tree

3 files changed

+77
-50
lines changed

3 files changed

+77
-50
lines changed

internal/grpc/services/gateway/gateway.go

+61-17
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ import (
2929
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
3030
"github.com/cs3org/reva/pkg/errtypes"
3131
"github.com/cs3org/reva/pkg/rgrpc"
32+
"github.com/cs3org/reva/pkg/share/cache"
3233
"github.com/cs3org/reva/pkg/sharedconf"
3334
"github.com/cs3org/reva/pkg/token"
3435
"github.com/cs3org/reva/pkg/token/manager/registry"
3536
"github.com/cs3org/reva/pkg/utils/cfg"
37+
"github.com/cs3org/reva/pkg/utils/resourceid"
3638
"google.golang.org/grpc"
3739
)
3840

@@ -65,13 +67,18 @@ type config struct {
6567
TransferExpires int64 `mapstructure:"transfer_expires"`
6668
TokenManager string `mapstructure:"token_manager"`
6769
// ShareFolder is the location where to create shares in the recipient's storage provider.
68-
ShareFolder string `mapstructure:"share_folder"`
69-
DataTransfersFolder string `mapstructure:"data_transfers_folder"`
70-
HomeMapping string `mapstructure:"home_mapping"`
71-
TokenManagers map[string]map[string]interface{} `mapstructure:"token_managers"`
72-
EtagCacheTTL int `mapstructure:"etag_cache_ttl"`
73-
AllowedUserAgents map[string][]string `mapstructure:"allowed_user_agents"` // map[path][]user-agent
74-
CreateHomeCacheTTL int `mapstructure:"create_home_cache_ttl"`
70+
ShareFolder string `mapstructure:"share_folder"`
71+
DataTransfersFolder string `mapstructure:"data_transfers_folder"`
72+
HomeMapping string `mapstructure:"home_mapping"`
73+
TokenManagers map[string]map[string]interface{} `mapstructure:"token_managers"`
74+
AllowedUserAgents map[string][]string `mapstructure:"allowed_user_agents"` // map[path][]user-agent
75+
CacheWarmupDriver string `mapstructure:"cache_warmup_driver"`
76+
CacheWarmupDrivers map[string]map[string]interface{} `mapstructure:"cache_warmup_drivers"`
77+
EtagCacheTTL int `mapstructure:"etag_cache_ttl"`
78+
CreateHomeCacheTTL int `mapstructure:"create_home_cache_ttl"`
79+
ResourceInfoCacheDriver string `mapstructure:"resource_info_cache_type"`
80+
ResourceInfoCacheTTL int `mapstructure:"resource_info_cache_ttl"`
81+
ResourceInfoCacheDrivers map[string]map[string]interface{} `mapstructure:"resource_info_caches"`
7582
}
7683

7784
// sets defaults.
@@ -116,11 +123,13 @@ func (c *config) ApplyDefaults() {
116123
}
117124

118125
type svc struct {
119-
c *config
120-
dataGatewayURL url.URL
121-
tokenmgr token.Manager
122-
etagCache *ttlcache.Cache `mapstructure:"etag_cache"`
123-
createHomeCache *ttlcache.Cache `mapstructure:"create_home_cache"`
126+
c *config
127+
dataGatewayURL url.URL
128+
tokenmgr token.Manager
129+
etagCache *ttlcache.Cache `mapstructure:"etag_cache"`
130+
createHomeCache *ttlcache.Cache `mapstructure:"create_home_cache"`
131+
resourceInfoCache cache.ResourceInfoCache
132+
resourceInfoCacheTTL time.Duration
124133
}
125134

126135
// New creates a new gateway svc that acts as a proxy for any grpc operation.
@@ -151,12 +160,21 @@ func New(ctx context.Context, m map[string]interface{}) (rgrpc.Service, error) {
151160
_ = createHomeCache.SetTTL(time.Duration(c.CreateHomeCacheTTL) * time.Second)
152161
createHomeCache.SkipTTLExtensionOnHit(true)
153162

163+
rCache, _ := getCacheManager(c)
164+
if c.ResourceInfoCacheTTL > 0 {
165+
cwm, err := getCacheWarmupManager(c)
166+
if err == nil {
167+
go startCacheWarmup(cwm, rCache, c.ResourceInfoCacheTTL)
168+
}
169+
}
170+
154171
s := &svc{
155-
c: &c,
156-
dataGatewayURL: *u,
157-
tokenmgr: tokenManager,
158-
etagCache: etagCache,
159-
createHomeCache: createHomeCache,
172+
c: &c,
173+
dataGatewayURL: *u,
174+
tokenmgr: tokenManager,
175+
etagCache: etagCache,
176+
createHomeCache: createHomeCache,
177+
resourceInfoCache: rCache,
160178
}
161179

162180
return s, nil
@@ -217,3 +235,29 @@ func getTokenManager(manager string, m map[string]map[string]interface{}) (token
217235

218236
return nil, errtypes.NotFound(fmt.Sprintf("driver %s not found for token manager", manager))
219237
}
238+
239+
func getCacheManager(c *config.Config) (cache.ResourceInfoCache, error) {
240+
if f, ok := cachereg.NewFuncs[c.ResourceInfoCacheDriver]; ok {
241+
return f(c.ResourceInfoCacheDrivers[c.ResourceInfoCacheDriver])
242+
}
243+
return nil, fmt.Errorf("driver not found: %s", c.ResourceInfoCacheDriver)
244+
}
245+
246+
func getCacheWarmupManager(c *config.Config) (cache.Warmup, error) {
247+
if f, ok := warmupreg.NewFuncs[c.CacheWarmupDriver]; ok {
248+
return f(c.CacheWarmupDrivers[c.CacheWarmupDriver])
249+
}
250+
return nil, fmt.Errorf("driver not found: %s", c.CacheWarmupDriver)
251+
}
252+
253+
func startCacheWarmup(cw cache.Warmup, rCache cache.ResourceInfoCache, ttl Duration) {
254+
time.Sleep(2 * time.Second)
255+
infos, err := cw.GetResourceInfos()
256+
if err != nil {
257+
return
258+
}
259+
for _, r := range infos {
260+
key := resourceid.OwnCloudResourceIDWrap(r.Id)
261+
_ = h.resourceInfoCache.SetWithExpire(key, r, h.resourceInfoCacheTTL)
262+
}
263+
}

internal/grpc/services/gateway/usershareprovider.go

+1
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ func (s *svc) ListExistingReceivedShares(ctx context.Context, req *collaboration
328328
}
329329

330330
// TODO(lopresti) incorporate the cache layer from internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go
331+
//s.resourceInfoCache
331332
stat, err := s.Stat(ctx, &provider.StatRequest{
332333
Ref: &provider.Reference{
333334
ResourceId: rs.Share.ResourceId,

internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go

+15-33
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import (
4848
"github.com/cs3org/reva/internal/http/services/owncloud/ocs/conversions"
4949
"github.com/cs3org/reva/internal/http/services/owncloud/ocs/response"
5050
"github.com/cs3org/reva/pkg/appctx"
51-
"github.com/cs3org/reva/pkg/spaces"
5251

5352
"github.com/cs3org/reva/pkg/notification"
5453
"github.com/cs3org/reva/pkg/notification/notificationhelper"
@@ -150,24 +149,18 @@ func (h *Handler) startCacheWarmup(c cache.Warmup) {
150149
}
151150
}
152151

153-
func (h *Handler) extractReference(r *http.Request) (*provider.Reference, error) {
152+
func (h *Handler) extractReference(r *http.Request) (provider.Reference, error) {
154153
var ref provider.Reference
155-
if spaceID := r.FormValue("space_ref"); spaceID != "" {
156-
_, base, _, ok := spaces.DecodeResourceID(spaceID)
157-
if !ok {
158-
return nil, errors.New("bad space id format")
159-
}
160-
161-
ref.Path = base
162-
}
163154
if p := r.FormValue("path"); p != "" {
164-
if ref.Path == "" {
165-
ref.Path = path.Join(h.homeNamespace, p)
166-
} else {
167-
ref.Path = path.Join(ref.Path, p)
155+
ref = provider.Reference{Path: path.Join(h.homeNamespace, p)}
156+
} else if spaceRef := r.FormValue("space_ref"); spaceRef != "" {
157+
var err error
158+
ref, err = utils.ParseStorageSpaceReference(spaceRef)
159+
if err != nil {
160+
return provider.Reference{}, err
168161
}
169162
}
170-
return &ref, nil
163+
return ref, nil
171164
}
172165

173166
// CreateShare handles POST requests on /apps/files_sharing/api/v1/shares.
@@ -193,7 +186,7 @@ func (h *Handler) CreateShare(w http.ResponseWriter, r *http.Request) {
193186
}
194187

195188
statReq := provider.StatRequest{
196-
Ref: ref,
189+
Ref: &ref,
197190
}
198191

199192
log := appctx.GetLogger(ctx).With().Interface("ref", ref).Logger()
@@ -1117,12 +1110,8 @@ func (h *Handler) addFilters(w http.ResponseWriter, r *http.Request, prefix stri
11171110
return nil, nil, err
11181111
}
11191112

1120-
target, err := h.extractReference(r)
1121-
if err != nil {
1122-
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error extracting reference from request", err)
1123-
return nil, nil, err
1124-
}
1125-
info, status, err := h.getResourceInfoByPath(ctx, client, target.Path)
1113+
target := path.Join(prefix, r.FormValue("path"))
1114+
info, status, err := h.getResourceInfoByPath(ctx, client, target)
11261115
if err != nil {
11271116
response.WriteOCSError(w, r, response.MetaServerError.StatusCode, "error sending a grpc stat request", err)
11281117
return nil, nil, err
@@ -1145,10 +1134,6 @@ func (h *Handler) addFilters(w http.ResponseWriter, r *http.Request, prefix stri
11451134
return collaborationFilters, linkFilters, nil
11461135
}
11471136

1148-
func relativePathToSpaceID(info *provider.ResourceInfo) string {
1149-
return strings.TrimPrefix(info.Path, info.Id.SpaceId)
1150-
}
1151-
11521137
func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, info *provider.ResourceInfo) error {
11531138
log := appctx.GetLogger(ctx)
11541139
if info != nil {
@@ -1161,14 +1146,12 @@ func (h *Handler) addFileInfo(ctx context.Context, s *conversions.ShareData, inf
11611146
s.MimeType = parsedMt
11621147
// TODO STime: &types.Timestamp{Seconds: info.Mtime.Seconds, Nanos: info.Mtime.Nanos},
11631148
// TODO Storage: int
1164-
itemID := spaces.EncodeResourceID(info.Id)
1165-
1166-
s.ItemSource = itemID
1149+
s.ItemSource = resourceid.OwnCloudResourceIDWrap(info.Id)
11671150
s.FileSource = s.ItemSource
11681151
switch {
11691152
case h.sharePrefix == "/":
1170-
s.FileTarget = relativePathToSpaceID(info)
1171-
s.Path = relativePathToSpaceID(info)
1153+
s.FileTarget = info.Path
1154+
s.Path = info.Path
11721155
case s.ShareType == conversions.ShareTypePublicLink:
11731156
s.FileTarget = path.Join("/", path.Base(info.Path))
11741157
s.Path = path.Join("/", path.Base(info.Path))
@@ -1404,8 +1387,7 @@ func mapState(state collaboration.ShareState) int {
14041387
var mapped int
14051388
switch state {
14061389
case collaboration.ShareState_SHARE_STATE_PENDING:
1407-
mapped = ocsStateAccepted
1408-
// mapped = ocsStatePending
1390+
mapped = ocsStatePending
14091391
case collaboration.ShareState_SHARE_STATE_ACCEPTED:
14101392
mapped = ocsStateAccepted
14111393
case collaboration.ShareState_SHARE_STATE_REJECTED:

0 commit comments

Comments
 (0)