frostfs-node/pkg/local_object_storage/engine/head.go
Leonard Lyubich 6f8c45d61b [#176] localstore: Change multiple access sync
In previous implementation each operation on local storage
locked engine mutex. This was done under the assumption that
the weights of the shards change as a result of write operations.
With the transition to static weights of shards, it is no longer
necessary to lock the global mutex during the execution of operations.
However, since the set of engine shards is dynamic, there is still a
need to control multiple access to this set. The same mutex is used
for synchronization.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2020-12-11 17:19:37 +03:00

75 lines
1.7 KiB
Go

package engine
import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard"
"github.com/pkg/errors"
"go.uber.org/zap"
)
// HeadPrm groups the parameters of Head operation.
type HeadPrm struct {
addr *objectSDK.Address
}
// HeadRes groups resulting values of Head operation.
type HeadRes struct {
head *object.Object
}
// WithAddress is a Head option to set the address of the requested object.
//
// Option is required.
func (p *HeadPrm) WithAddress(addr *objectSDK.Address) *HeadPrm {
if p != nil {
p.addr = addr
}
return p
}
// Header returns the requested object header.
//
// Instance has empty payload.
func (r *HeadRes) Header() *object.Object {
return r.head
}
// Head reads object header from local storage.
//
// Returns any error encountered that
// did not allow to completely read the object header.
//
// Returns ErrObjectNotFound if requested object is missing in local storage.
func (e *StorageEngine) Head(prm *HeadPrm) (*HeadRes, error) {
var head *object.Object
shPrm := new(shard.GetPrm).
WithAddress(prm.addr)
e.iterateOverSortedShards(prm.addr, func(sh *shard.Shard) (stop bool) {
res, err := sh.Get(shPrm)
if err != nil {
if !errors.Is(err, shard.ErrObjectNotFound) {
// TODO: smth wrong with shard, need to be processed
e.log.Warn("could not get object from shard",
zap.Stringer("shard", sh.ID()),
zap.String("error", err.Error()),
)
}
} else {
head = res.Object()
}
return err == nil
})
if head == nil {
return nil, ErrObjectNotFound
}
return &HeadRes{
head: head,
}, nil
}