[#2198] blobovniczatree: Properly handle concurrent active blobovnicza update

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2023-01-12 16:29:39 +03:00
parent 58dd309abe
commit 847a262ece

View file

@ -6,6 +6,7 @@ import (
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza" "github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobovnicza"
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
"go.etcd.io/bbolt"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -45,11 +46,14 @@ func (b *Blobovniczas) Put(prm common.PutPrm) (common.PutRes, error) {
} }
if _, err := active.blz.Put(putPrm); err != nil { if _, err := active.blz.Put(putPrm); err != nil {
// check if blobovnicza is full // Check if blobovnicza is full. We could either receive `blobovnicza.ErrFull` error
if errors.Is(err, blobovnicza.ErrFull) { // or update active blobovnicza in other thread. In the latter case the database will be closed
b.log.Debug("blobovnicza overflowed", // and `updateActive` takes care of not updating the active blobovnicza twice.
zap.String("path", filepath.Join(p, u64ToHexString(active.ind))), if isFull := errors.Is(err, blobovnicza.ErrFull); isFull || errors.Is(err, bbolt.ErrDatabaseNotOpen) {
) if isFull {
b.log.Debug("blobovnicza overflowed",
zap.String("path", filepath.Join(p, u64ToHexString(active.ind))))
}
if err := b.updateActive(p, &active.ind); err != nil { if err := b.updateActive(p, &active.ind); err != nil {
if !isLogical(err) { if !isLogical(err) {