package blobovniczatree import ( "context" "strings" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util" "go.uber.org/zap" "golang.org/x/sync/errgroup" ) // Open opens blobovnicza tree. func (b *Blobovniczas) Open(mode mode.ComponentMode) error { b.readOnly = mode.ReadOnly() b.metrics.SetMode(mode) b.metrics.SetRebuildStatus(rebuildStatusNotStarted) b.openManagers() return nil } // Init initializes blobovnicza tree. // // Should be called exactly once. func (b *Blobovniczas) Init() error { b.log.Debug(context.Background(), logs.BlobovniczatreeInitializingBlobovniczas) if b.readOnly { b.log.Debug(context.Background(), logs.BlobovniczatreeReadonlyModeSkipBlobovniczasInitialization) return nil } return b.initializeDBs(context.TODO()) } func (b *Blobovniczas) initializeDBs(ctx context.Context) error { err := util.MkdirAllX(b.rootPath, b.perm) if err != nil { return err } eg, egCtx := errgroup.WithContext(ctx) eg.SetLimit(b.blzInitWorkerCount) err = b.iterateIncompletedRebuildDBPaths(egCtx, func(p string) (bool, error) { eg.Go(func() error { p = strings.TrimSuffix(p, rebuildSuffix) shBlz := b.getBlobovniczaWithoutCaching(p) blz, err := shBlz.Open(egCtx) if err != nil { return err } defer shBlz.Close(egCtx) moveInfo, err := blz.ListMoveInfo(egCtx) if err != nil { return err } for _, move := range moveInfo { b.deleteProtectedObjects.Add(move.Address) } b.log.Debug(egCtx, logs.BlobovniczatreeBlobovniczaSuccessfullyInitializedClosing, zap.String("id", p)) return nil }) return false, nil }) if err != nil { _ = eg.Wait() return err } return eg.Wait() } func (b *Blobovniczas) openManagers() { b.commondbManager.Open() // order important b.activeDBManager.Open() b.dbCache.Open() } // Close implements common.Storage. func (b *Blobovniczas) Close(ctx context.Context) error { b.dbCache.Close() // order important b.activeDBManager.Close(ctx) b.commondbManager.Close() return nil } // returns blobovnicza with path p // // If blobovnicza is already cached, instance from cache is returned w/o changes. func (b *Blobovniczas) getBlobovnicza(ctx context.Context, p string) *sharedDB { return b.dbCache.GetOrCreate(ctx, p) } func (b *Blobovniczas) getBlobovniczaWithoutCaching(p string) *sharedDB { return b.commondbManager.GetByPath(p) }