[#1421] engine: Use LockPrm to store Lock operation parameters
All checks were successful
Tests and linters / Run gofumpt (pull_request) Successful in 3m6s
DCO action / DCO (pull_request) Successful in 3m43s
Tests and linters / Staticcheck (pull_request) Successful in 5m19s
Vulncheck / Vulncheck (pull_request) Successful in 6m38s
Build / Build Components (pull_request) Successful in 7m31s
Pre-commit hooks / Pre-commit (pull_request) Successful in 7m30s
Tests and linters / Tests (pull_request) Successful in 7m52s
Tests and linters / gopls check (pull_request) Successful in 8m9s
Tests and linters / Tests with -race (pull_request) Successful in 8m12s
Tests and linters / Lint (pull_request) Successful in 8m22s

Signed-off-by: Aleksey Savchuk <a.savchuk@yadro.com>
This commit is contained in:
Aleksey Savchuk 2024-12-11 16:24:44 +03:00
parent 7b870ec429
commit 6f28a52e1a
Signed by: a-savchuk
GPG key ID: 70C0A7FF6F9C4639
3 changed files with 56 additions and 11 deletions

View file

@ -481,7 +481,12 @@ func (e engineWithoutNotifications) Delete(ctx context.Context, tombstone oid.Ad
}
func (e engineWithoutNotifications) Lock(ctx context.Context, locker oid.Address, toLock []oid.ID) error {
return e.engine.Lock(ctx, locker.Container(), locker.Object(), toLock)
var prm engine.LockPrm
prm.WithContainer(locker.Container())
prm.WithTarget(locker.Object(), toLock...)
_, err := e.engine.Lock(ctx, prm)
return err
}
func (e engineWithoutNotifications) Put(ctx context.Context, o *objectSDK.Object, indexedContainer bool) error {

View file

@ -16,6 +16,30 @@ import (
"go.uber.org/zap"
)
// LockPrm contains parameters for Lock operation.
type LockPrm struct {
cnt cid.ID
lock oid.ID
locked []oid.ID
}
// WithContainer sets the container ID for both the lock and locked objects
// since they must belong to the same container.
func (p *LockPrm) WithContainer(cnt cid.ID) {
p.cnt = cnt
}
// WithTarget sets lock object ID and IDs of objects to be locked.
//
// The list of locked objects should be unique. Panics if the list is empty.
func (p *LockPrm) WithTarget(lock oid.ID, locked ...oid.ID) {
p.lock = lock
p.locked = locked
}
// LockPrm contains results for Lock operation.
type LockRes struct{}
var errLockFailed = errors.New("lock operation failed")
// Lock marks objects as locked with another object. All objects from the
@ -24,7 +48,11 @@ var errLockFailed = errors.New("lock operation failed")
// Allows locking regular objects only (otherwise returns apistatus.LockNonRegularObject).
//
// Locked list should be unique. Panics if it is empty.
func (e *StorageEngine) Lock(ctx context.Context, idCnr cid.ID, locker oid.ID, locked []oid.ID) error {
func (e *StorageEngine) Lock(ctx context.Context, prm LockPrm) (LockRes, error) {
idCnr := prm.cnt
locker := prm.lock
locked := prm.locked
ctx, span := tracing.StartSpanFromContext(ctx, "StorageEngine.Lock",
trace.WithAttributes(
attribute.String("container_id", idCnr.EncodeToString()),
@ -34,7 +62,7 @@ func (e *StorageEngine) Lock(ctx context.Context, idCnr cid.ID, locker oid.ID, l
defer span.End()
defer elapsed("Lock", e.metrics.AddMethodDuration)()
return e.execIfNotBlocked(func() error {
return LockRes{}, e.execIfNotBlocked(func() error {
return e.lock(ctx, idCnr, locker, locked)
})
}

View file

@ -106,7 +106,11 @@ func TestLockUserScenario(t *testing.T) {
err = Put(context.Background(), e, lockerObj, false)
require.NoError(t, err)
err = e.Lock(context.Background(), cnr, lockerID, []oid.ID{id})
var lockPrm LockPrm
lockPrm.WithContainer(cnr)
lockPrm.WithTarget(lockerID, id)
_, err = e.Lock(context.Background(), lockPrm)
require.NoError(t, err)
// 3.
@ -191,7 +195,11 @@ func TestLockExpiration(t *testing.T) {
id, _ := obj.ID()
idLock, _ := lock.ID()
err = e.Lock(context.Background(), cnr, idLock, []oid.ID{id})
var lockPrm LockPrm
lockPrm.WithContainer(cnr)
lockPrm.WithTarget(idLock, id)
_, err = e.Lock(context.Background(), lockPrm)
require.NoError(t, err)
var inhumePrm InhumePrm
@ -262,7 +270,11 @@ func TestLockForceRemoval(t *testing.T) {
id, _ := obj.ID()
idLock, _ := lock.ID()
err = e.Lock(context.Background(), cnr, idLock, []oid.ID{id})
var lockPrm LockPrm
lockPrm.WithContainer(cnr)
lockPrm.WithTarget(idLock, id)
_, err = e.Lock(context.Background(), lockPrm)
require.NoError(t, err)
// 3.
@ -327,11 +339,11 @@ func TestLockExpiredRegularObject(t *testing.T) {
require.ErrorAs(t, err, &errNotFound)
t.Run("lock expired regular object", func(t *testing.T) {
err := engine.Lock(context.Background(),
address.Container(),
oidtest.ID(),
[]oid.ID{address.Object()},
)
var lockPrm LockPrm
lockPrm.WithContainer(address.Container())
lockPrm.WithTarget(oidtest.ID(), address.Object())
_, err := engine.Lock(context.Background(), lockPrm)
require.NoError(t, err)
res, err := engine.IsLocked(context.Background(), objectcore.AddressOf(object))