Skip to content

Commit

Permalink
Incorporate cache for ListExistingShares
Browse files Browse the repository at this point in the history
  • Loading branch information
Jesse Geens committed Jan 28, 2025
1 parent 3477795 commit 6534abc
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 38 deletions.
44 changes: 32 additions & 12 deletions internal/grpc/services/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/rgrpc"
"github.com/cs3org/reva/pkg/share/cache"
cachereg "github.com/cs3org/reva/pkg/share/cache/registry"
"github.com/cs3org/reva/pkg/sharedconf"
"github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/token/manager/registry"
Expand Down Expand Up @@ -65,13 +67,16 @@ type config struct {
TransferExpires int64 `mapstructure:"transfer_expires"`
TokenManager string `mapstructure:"token_manager"`
// ShareFolder is the location where to create shares in the recipient's storage provider.
ShareFolder string `mapstructure:"share_folder"`
DataTransfersFolder string `mapstructure:"data_transfers_folder"`
HomeMapping string `mapstructure:"home_mapping"`
TokenManagers map[string]map[string]interface{} `mapstructure:"token_managers"`
EtagCacheTTL int `mapstructure:"etag_cache_ttl"`
AllowedUserAgents map[string][]string `mapstructure:"allowed_user_agents"` // map[path][]user-agent
CreateHomeCacheTTL int `mapstructure:"create_home_cache_ttl"`
ShareFolder string `mapstructure:"share_folder"`
DataTransfersFolder string `mapstructure:"data_transfers_folder"`
HomeMapping string `mapstructure:"home_mapping"`
TokenManagers map[string]map[string]interface{} `mapstructure:"token_managers"`
EtagCacheTTL int `mapstructure:"etag_cache_ttl"`
AllowedUserAgents map[string][]string `mapstructure:"allowed_user_agents"` // map[path][]user-agent
CreateHomeCacheTTL int `mapstructure:"create_home_cache_ttl"`
ResourceInfoCacheDriver string `mapstructure:"resource_info_cache_type"`
ResourceInfoCacheTTL int `mapstructure:"resource_info_cache_ttl"`
ResourceInfoCacheDrivers map[string]map[string]interface{} `mapstructure:"resource_info_caches"`
}

// sets defaults.
Expand Down Expand Up @@ -116,11 +121,13 @@ func (c *config) ApplyDefaults() {
}

type svc struct {
c *config
dataGatewayURL url.URL
tokenmgr token.Manager
etagCache *ttlcache.Cache `mapstructure:"etag_cache"`
createHomeCache *ttlcache.Cache `mapstructure:"create_home_cache"`
c *config
dataGatewayURL url.URL
tokenmgr token.Manager
etagCache *ttlcache.Cache `mapstructure:"etag_cache"`
createHomeCache *ttlcache.Cache `mapstructure:"create_home_cache"`
resourceInfoCache cache.ResourceInfoCache
resourceInfoCacheTTL time.Duration
}

// New creates a new gateway svc that acts as a proxy for any grpc operation.
Expand Down Expand Up @@ -159,6 +166,12 @@ func New(ctx context.Context, m map[string]interface{}) (rgrpc.Service, error) {
createHomeCache: createHomeCache,
}

ricache, err := getCacheManager(&c)
if err == nil {
s.resourceInfoCache = ricache
s.resourceInfoCacheTTL = time.Second * time.Duration(c.ResourceInfoCacheTTL)
}

return s, nil
}

Expand Down Expand Up @@ -217,3 +230,10 @@ func getTokenManager(manager string, m map[string]map[string]interface{}) (token

return nil, errtypes.NotFound(fmt.Sprintf("driver %s not found for token manager", manager))
}

func getCacheManager(c *config) (cache.ResourceInfoCache, error) {
if f, ok := cachereg.NewFuncs[c.ResourceInfoCacheDriver]; ok {
return f(c.ResourceInfoCacheDrivers[c.ResourceInfoCacheDriver])
}
return nil, fmt.Errorf("driver not found: %s", c.ResourceInfoCacheDriver)
}
71 changes: 45 additions & 26 deletions internal/grpc/services/gateway/usershareprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/utils/resourceid"

"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/rgrpc/status"
Expand Down Expand Up @@ -184,6 +185,7 @@ func (s *svc) ListShares(ctx context.Context, req *collaboration.ListSharesReque
return &collaboration.ListSharesResponse{
Status: status.NewInternal(ctx, err, "error getting user share provider client"),
}, nil

}

res, err := c.ListShares(ctx, req)
Expand All @@ -205,25 +207,34 @@ func (s *svc) ListExistingShares(ctx context.Context, req *collaboration.ListSha

sharesCh := make(chan *gateway.ShareResourceInfo, len(shares.Shares))
pool := pond.NewPool(50)
// TODO(lopresti) incorporate the cache layer from internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go

for _, share := range shares.Shares {
share := share
pool.SubmitErr(func() error {
stat, err := s.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
ResourceId: share.ResourceId,
},
})
if err != nil {
return err
}
if stat.Status.Code != rpc.Code_CODE_OK {
return errors.New("An error occurred: " + stat.Status.Message)
key := resourceid.OwnCloudResourceIDWrap(share.ResourceId)
var resourceInfo *provider.ResourceInfo
if res, err := s.resourceInfoCache.Get(key); err == nil && res != nil {
resourceInfo = res
} else {
stat, err := s.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
ResourceId: share.ResourceId,
},
})
if err != nil {
return err
}
if stat.Status.Code != rpc.Code_CODE_OK {
return errors.New("An error occurred: " + stat.Status.Message)
}
resourceInfo = stat.Info
if s.resourceInfoCacheTTL > 0 {
_ = s.resourceInfoCache.SetWithExpire(key, resourceInfo, s.resourceInfoCacheTTL)
}
}

sharesCh <- &gateway.ShareResourceInfo{
ResourceInfo: stat.Info,
ResourceInfo: resourceInfo,
Share: share,
}
return nil
Expand Down Expand Up @@ -330,25 +341,33 @@ func (s *svc) ListExistingReceivedShares(ctx context.Context, req *collaboration
for _, rs := range rshares.Shares {
rs := rs
pool.SubmitErr(func() error {
if rs.State == collaboration.ShareState_SHARE_STATE_REJECTED || rs.State == collaboration.ShareState_SHARE_STATE_INVALID {
if rs.State == collaboration.ShareState_SHARE_STATE_INVALID {
return errors.New("Invalid Share State")
}

// TODO(lopresti) incorporate the cache layer from internal/http/services/owncloud/ocs/handlers/apps/sharing/shares/shares.go
stat, err := s.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
ResourceId: rs.Share.ResourceId,
},
})
if err != nil {
return err
}
if stat.Status.Code != rpc.Code_CODE_OK {
return errors.New("An error occurred: " + stat.Status.Message)
key := resourceid.OwnCloudResourceIDWrap(rs.Share.ResourceId)
var resourceInfo *provider.ResourceInfo
if res, err := s.resourceInfoCache.Get(key); err == nil && res != nil {
resourceInfo = res
} else {
stat, err := s.Stat(ctx, &provider.StatRequest{
Ref: &provider.Reference{
ResourceId: rs.Share.ResourceId,
},
})
if err != nil {
return err
}
if stat.Status.Code != rpc.Code_CODE_OK {
return errors.New("An error occurred: " + stat.Status.Message)
}
resourceInfo = stat.Info
if s.resourceInfoCacheTTL > 0 {
_ = s.resourceInfoCache.SetWithExpire(key, resourceInfo, s.resourceInfoCacheTTL)
}
}

sharesCh <- &gateway.ReceivedShareResourceInfo{
ResourceInfo: stat.Info,
ResourceInfo: resourceInfo,
ReceivedShare: rs,
}
return nil
Expand Down

0 comments on commit 6534abc

Please sign in to comment.