package writecache import ( "context" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr" "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) // Put puts object to write-cache. // // Returns ErrReadOnly if write-cache is in R/O mode. // Returns ErrNotInitialized if write-cache has not been initialized yet. // Returns ErrOutOfSpace if saving an object leads to WC's size overflow. // Returns ErrBigObject if an objects exceeds maximum object size. func (c *cache) Put(ctx context.Context, prm common.PutPrm) (common.PutRes, error) { ctx, span := tracing.StartSpanFromContext(ctx, "writecache.Put", trace.WithAttributes( attribute.String("address", prm.Address.EncodeToString()), attribute.Bool("dont_compress", prm.DontCompress), )) defer span.End() startedAt := time.Now() added := false storageType := StorageTypeUndefined defer func() { c.metrics.Put(time.Since(startedAt), added, storageType) }() if !c.modeMtx.TryRLock() { return common.PutRes{}, ErrNotInitialized } defer c.modeMtx.RUnlock() if c.readOnly() { return common.PutRes{}, ErrReadOnly } if c.noMetabase() { return common.PutRes{}, ErrDegraded } sz := uint64(len(prm.RawData)) if sz > c.maxObjectSize { return common.PutRes{}, ErrBigObject } storageType = StorageTypeFSTree err := c.putBig(ctx, prm) if err == nil { added = true } return common.PutRes{}, metaerr.Wrap(err) } // putBig writes object to FSTree and pushes it to the flush workers queue. func (c *cache) putBig(ctx context.Context, prm common.PutPrm) error { if !c.hasEnoughSpaceFS() { return ErrOutOfSpace } _, err := c.fsTree.Put(ctx, prm) if err != nil { return err } storagelog.Write(c.log, storagelog.AddressField(prm.Address.EncodeToString()), storagelog.StorageTypeField(wcStorageType), storagelog.OpField("fstree PUT"), ) // counter changed by fstree c.estimateCacheSize() return nil }