package blobstor import ( "context" "encoding/hex" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "go.uber.org/zap" ) // Exists checks if the object is presented in BLOB storage. // // Returns any error encountered that did not allow // to completely check object existence. func (b *BlobStor) Exists(ctx context.Context, prm common.ExistsPrm) (common.ExistsRes, error) { var ( exists = false startedAt = time.Now() ) defer func() { b.metrics.Exists(time.Since(startedAt), exists, prm.StorageID != nil) }() ctx, span := tracing.StartSpanFromContext(ctx, "BlobStor.Exists", trace.WithAttributes( attribute.String("address", prm.Address.EncodeToString()), attribute.String("storage_id", hex.EncodeToString(prm.StorageID)), )) defer span.End() b.modeMtx.RLock() defer b.modeMtx.RUnlock() var errors []error for _, storage := range b.selectStorages(prm.StorageID) { res, err := storage.Exists(ctx, prm) if err == nil && res.Exists { exists = true return res, nil } else if err != nil { errors = append(errors, err) } } if len(errors) == 0 { return common.ExistsRes{}, nil } for _, err := range errors[:len(errors)-1] { b.log.Warn(logs.BlobstorErrorOccurredDuringObjectExistenceChecking, zap.Stringer("address", prm.Address), zap.String("error", err.Error())) } return common.ExistsRes{}, errors[len(errors)-1] }