Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cache to store UID to UserID mapping in EOS #1340

Merged
merged 4 commits into from
Dec 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/unreleased/eos-user-cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Add cache to store UID to UserID mapping in EOS

Previously, we used to send an RPC to the user provider service for every lookup
of user IDs from the UID stored in EOS. This PR adds an in-memory lock-protected
cache to store this mapping.

https://github.com/cs3org/reva/pull/1340
2 changes: 1 addition & 1 deletion internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2016,7 +2016,7 @@ func (s *svc) split(ctx context.Context, p string, i int) bool {

// validate that we have always at least two elements
if len(parts) < 2 {
panic(fmt.Sprintf("split: len(parts) < 2: path:%s parts:%+v", p, parts))
return false
}

// validate the share folder is always the second element, first element is always the hardcoded value of "home"
Expand Down
13 changes: 9 additions & 4 deletions pkg/publicshare/manager/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,16 +363,19 @@ func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters []
// RevokePublicShare undocumented.
func (m *manager) RevokePublicShare(ctx context.Context, u *user.User, ref *link.PublicShareReference) error {
m.mutex.Lock()
defer m.mutex.Unlock()

db, err := m.readDb()
if err != nil {
return err
}
m.mutex.Unlock()

switch {
case ref.GetId().OpaqueId != "":
delete(db, ref.GetId().OpaqueId)
case ref.GetId() != nil && ref.GetId().OpaqueId != "":
if _, ok := db[ref.GetId().OpaqueId]; ok {
delete(db, ref.GetId().OpaqueId)
} else {
return errors.New("reference does not exist")
}
case ref.GetToken() != "":
share, err := m.getByToken(ctx, ref.GetToken())
if err != nil {
Expand All @@ -383,6 +386,8 @@ func (m *manager) RevokePublicShare(ctx context.Context, u *user.User, ref *link
return errors.New("reference does not exist")
}

m.mutex.Lock()
defer m.mutex.Unlock()
return m.writeDb(db)
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/publicshare/manager/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (m *manager) ListPublicShares(ctx context.Context, u *user.User, filters []
func (m *manager) RevokePublicShare(ctx context.Context, u *user.User, ref *link.PublicShareReference) error {
// check whether the reference exists
switch {
case ref.GetId().OpaqueId != "":
case ref.GetId() != nil && ref.GetId().OpaqueId != "":
s, err := m.getPublicShareByTokenID(ctx, *ref.GetId())
if err != nil {
return errors.New("reference does not exist")
Expand Down
9 changes: 9 additions & 0 deletions pkg/storage/utils/eosfs/eosfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"regexp"
"strconv"
"strings"
"sync"

userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
Expand Down Expand Up @@ -179,6 +180,7 @@ type eosfs struct {
chunkHandler *chunking.ChunkHandler
singleUserUID string
singleUserGID string
userIDCache sync.Map
}

// NewEOSFS returns a storage.FS interface implementation that connects to an
Expand Down Expand Up @@ -213,6 +215,7 @@ func NewEOSFS(c *Config) (storage.FS, error) {
c: eosClient,
conf: c,
chunkHandler: chunking.NewChunkHandler(c.CacheDirectory),
userIDCache: sync.Map{},
}

return eosfs, nil
Expand Down Expand Up @@ -1455,6 +1458,10 @@ func (fs *eosfs) getUIDGateway(ctx context.Context, u *userpb.UserId) (string, s
}

func (fs *eosfs) getUserIDGateway(ctx context.Context, uid string) (*userpb.UserId, error) {
if userIDInterface, ok := fs.userIDCache.Load(uid); ok {
return userIDInterface.(*userpb.UserId), nil
}

client, err := pool.GetGatewayServiceClient(fs.conf.GatewaySvc)
if err != nil {
return nil, errors.Wrap(err, "eos: error getting gateway grpc client")
Expand All @@ -1469,6 +1476,8 @@ func (fs *eosfs) getUserIDGateway(ctx context.Context, uid string) (*userpb.User
if getUserResp.Status.Code != rpc.Code_CODE_OK {
return nil, errors.Wrap(err, "eos: grpc get user failed")
}

fs.userIDCache.Store(uid, getUserResp.User.Id)
return getUserResp.User.Id, nil
}

Expand Down