lazy initialize metadataclient

Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
jkoberg
2022-02-26 13:18:27 +01:00
parent 11a8b75b2e
commit 2452d01506
7 changed files with 64 additions and 10 deletions

View File

@@ -46,6 +46,7 @@ func (m *Manager) List(ctx context.Context, roleIDs []string) []*settingsmsg.Bun
res, err := m.roleService.ListRoles(ctx, request)
if err != nil {
m.logger.Debug().Err(err).Msg("failed to fetch roles by roleIDs")
return nil
}
for _, role := range res.Bundles {
m.cache.set(role.Id, role)

View File

@@ -88,6 +88,11 @@ func (g Service) CheckPermission(ctx context.Context, req *permissions.CheckPerm
// RegisterDefaultRoles composes default roles and saves them. Skipped if the roles already exist.
func (g Service) RegisterDefaultRoles() {
// TODO: we can't register on service start any more because metadata might not be up yet
// we need to lazy initialize
if true {
return
}
// FIXME: we're writing default roles per service start (i.e. twice at the moment, for http and grpc server). has to happen only once.
for _, role := range generateBundlesDefaultRoles() {
bundleID := role.Extension + "." + role.Id

View File

@@ -11,6 +11,7 @@ import (
// ListRoleAssignments loads and returns all role assignments matching the given assignment identifier.
func (s Store) ListRoleAssignments(accountUUID string) ([]*settingsmsg.UserRoleAssignment, error) {
s.Init()
assIDs, err := s.mdc.ReadDir(nil, accountPath(accountUUID))
if err != nil {
return nil, err
@@ -36,6 +37,7 @@ func (s Store) ListRoleAssignments(accountUUID string) ([]*settingsmsg.UserRoleA
// WriteRoleAssignment appends the given role assignment to the existing assignments of the respective account.
func (s Store) WriteRoleAssignment(accountUUID, roleID string) (*settingsmsg.UserRoleAssignment, error) {
s.Init()
// as per https://github.com/owncloud/product/issues/103 "Each user can have exactly one role"
err := s.mdc.Delete(nil, accountPath(accountUUID))
if err != nil {
@@ -61,6 +63,7 @@ func (s Store) WriteRoleAssignment(accountUUID, roleID string) (*settingsmsg.Use
// RemoveRoleAssignment deletes the given role assignment from the existing assignments of the respective account.
func (s Store) RemoveRoleAssignment(assignmentID string) error {
s.Init()
accounts, err := s.mdc.ReadDir(nil, accountsFolderLocation)
if err != nil {
return err

View File

@@ -11,6 +11,7 @@ import (
// ListBundles returns all bundles in the dataPath folder that match the given type.
func (s Store) ListBundles(bundleType settingsmsg.Bundle_Type, bundleIDs []string) ([]*settingsmsg.Bundle, error) {
s.Init()
var bundles []*settingsmsg.Bundle
for _, id := range bundleIDs {
b, err := s.mdc.SimpleDownload(nil, bundlePath(id))
@@ -34,6 +35,7 @@ func (s Store) ListBundles(bundleType settingsmsg.Bundle_Type, bundleIDs []strin
// ReadBundle tries to find a bundle by the given id within the dataPath.
func (s Store) ReadBundle(bundleID string) (*settingsmsg.Bundle, error) {
s.Init()
b, err := s.mdc.SimpleDownload(nil, bundlePath(bundleID))
if err != nil {
return nil, err
@@ -50,6 +52,7 @@ func (s Store) ReadSetting(settingID string) (*settingsmsg.Setting, error) {
// WriteBundle sends the givens record to the metadataclient. returns `record` for legacy reasons
func (s Store) WriteBundle(record *settingsmsg.Bundle) (*settingsmsg.Bundle, error) {
s.Init()
b, err := json.Marshal(record)
if err != nil {
return nil, err

View File

@@ -3,8 +3,8 @@ package store
import (
"context"
"fmt"
"log"
"sync"
"github.com/cs3org/reva/pkg/storage/utils/metadata"
olog "github.com/owncloud/ocis/ocis-pkg/log"
@@ -30,6 +30,7 @@ type MetadataClient interface {
Delete(ctx context.Context, id string) error
ReadDir(ctx context.Context, id string) ([]string, error)
MakeDirIfNotExist(ctx context.Context, id string) error
Init(ctx context.Context, id string) error
}
// Store interacts with the filesystem to manage settings information
@@ -37,6 +38,34 @@ type Store struct {
Logger olog.Logger
mdc MetadataClient
cfg *config.Config
init *sync.Once
l *sync.Mutex
}
// Init initialize the store once, later calls are noops
func (s Store) Init() {
if s.mdc != nil {
return
}
s.l.Lock()
defer s.l.Unlock()
var err error
s.init.Do(func() {
//b := backoff.NewExponentialBackOff()
//b.MaxElapsedTime = 4 * time.Second
//backoff.Retry(func() error {
err = s.initMetadataClient()
//return err
//}, b)
})
if err != nil {
log.Fatal(err)
}
}
// New creates a new store
@@ -48,9 +77,10 @@ func New(cfg *config.Config) settings.Manager {
//olog.Level(cfg.Log.Level),
//olog.File(cfg.Log.File),
//),
l: &sync.Mutex{},
init: &sync.Once{},
}
s.mdc = NewMetadataClient(cfg)
return &s
}
@@ -60,11 +90,17 @@ func NewMetadataClient(cfg *config.Config) MetadataClient {
if err != nil {
log.Fatal("error connecting to mdc:", err)
}
return mdc
fmt.Println(settingsSpaceID)
err = mdc.Init(nil, settingsSpaceID)
}
// we need to lazy initialize the MetadataClient because metadata service might not be ready
func (s Store) initMetadataClient() error {
s.mdc = NewMetadataClient(s.cfg)
err := s.mdc.Init(nil, settingsSpaceID)
if err != nil {
log.Fatal("error initializing mdc:", err)
return err
}
for _, p := range []string{
@@ -73,13 +109,12 @@ func NewMetadataClient(cfg *config.Config) MetadataClient {
bundleFolderLocation,
valuesFolderLocation,
} {
err = mdc.MakeDirIfNotExist(nil, p)
err = s.mdc.MakeDirIfNotExist(nil, p)
if err != nil {
log.Fatalf("error creating settings folder '%s': %s", p, err)
return err
}
}
return mdc
return nil
}
func init() {

View File

@@ -95,7 +95,12 @@ func (m *MockedMetadataClient) ReadDir(_ context.Context, id string) ([]string,
}
// MakeDirIfNotExist does nothing
func (m *MockedMetadataClient) MakeDirIfNotExist(_ context.Context, id string) error {
func (*MockedMetadataClient) MakeDirIfNotExist(_ context.Context, _ string) error {
return nil
}
// Init does nothing
func (*MockedMetadataClient) Init(_ context.Context, _ string) error {
return nil
}

View File

@@ -19,6 +19,7 @@ func (s Store) ListValues(bundleID, accountUUID string) ([]*settingsmsg.Value, e
// ReadValue tries to find a value by the given valueId within the dataPath
func (s Store) ReadValue(valueID string) (*settingsmsg.Value, error) {
s.Init()
b, err := s.mdc.SimpleDownload(nil, valuePath(valueID))
if err != nil {
return nil, err
@@ -34,6 +35,7 @@ func (s Store) ReadValueByUniqueIdentifiers(accountUUID, settingID string) (*set
// WriteValue writes the given value into a file within the dataPath
func (s Store) WriteValue(value *settingsmsg.Value) (*settingsmsg.Value, error) {
s.Init()
b, err := json.Marshal(value)
if err != nil {
return nil, err