From b42bcdc6fa6cca2cf8e5a5fbaf2c8cf82f957b37 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 17 Oct 2024 14:37:26 +0300 Subject: [PATCH] [#1433] services/object: Put object before auxiliary info Consider the following operations ordering: 1. Inhume(with tombstone A) --> add tombstone mark for an object 2. --> new epoch arives 3. --> GCMark is added for a tombstone A, because it is unavailable 4. Put(A) --> return error, because the object already has a GCMark It is possible, and I have successfully reproduced it with a test on the shard level. However, the error is related to the specific _ordering_ of operations with engine. And triggering race-conditions like this is only possible on a shard level currently, so no tests are written. Signed-off-by: Evgenii Stratonikov --- pkg/services/object/common/writer/local.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/services/object/common/writer/local.go b/pkg/services/object/common/writer/local.go index e219b44dd..cf3d03275 100644 --- a/pkg/services/object/common/writer/local.go +++ b/pkg/services/object/common/writer/local.go @@ -32,6 +32,10 @@ type LocalTarget struct { } func (t LocalTarget) WriteObject(ctx context.Context, obj *objectSDK.Object, meta objectCore.ContentMeta) error { + if err := t.Storage.Put(ctx, obj, containerCore.IsIndexedContainer(t.Container)); err != nil { + return fmt.Errorf("(%T) could not put object to local storage: %w", t, err) + } + switch meta.Type() { case objectSDK.TypeTombstone: err := t.Storage.Delete(ctx, objectCore.AddressOf(obj), meta.Objects()) @@ -47,8 +51,5 @@ func (t LocalTarget) WriteObject(ctx context.Context, obj *objectSDK.Object, met // objects that do not change meta storage } - if err := t.Storage.Put(ctx, obj, containerCore.IsIndexedContainer(t.Container)); err != nil { - return fmt.Errorf("(%T) could not put object to local storage: %w", t, err) - } return nil }