package engine import ( "context" "time" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/writecache" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/metrics" "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) // FlushWriteCachePrm groups the parameters of FlushWriteCache operation. type FlushWriteCachePrm struct { shardID *shard.ID ignoreErrors bool } // SetShardID is an option to set shard ID. // // Option is required. func (p *FlushWriteCachePrm) SetShardID(id *shard.ID) { p.shardID = id } // SetIgnoreErrors sets errors ignore flag.. func (p *FlushWriteCachePrm) SetIgnoreErrors(ignore bool) { p.ignoreErrors = ignore } // FlushWriteCacheRes groups the resulting values of FlushWriteCache operation. type FlushWriteCacheRes struct{} // FlushWriteCache flushes write-cache on a single shard. func (e *StorageEngine) FlushWriteCache(ctx context.Context, p FlushWriteCachePrm) (FlushWriteCacheRes, error) { ctx, span := tracing.StartSpanFromContext(ctx, "StorageEngine.FlushWriteCache", trace.WithAttributes( attribute.String("shard)id", p.shardID.String()), attribute.Bool("ignore_errors", p.ignoreErrors), )) defer span.End() e.mtx.RLock() sh, ok := e.shards[p.shardID.String()] e.mtx.RUnlock() if !ok { return FlushWriteCacheRes{}, errShardNotFound } var prm shard.FlushWriteCachePrm prm.SetIgnoreErrors(p.ignoreErrors) return FlushWriteCacheRes{}, sh.FlushWriteCache(ctx, prm) } type writeCacheMetrics struct { shardID string metrics metrics.WriteCacheMetrics } func (m *writeCacheMetrics) Get(d time.Duration, success bool, st writecache.StorageType) { m.metrics.AddMethodDuration(m.shardID, "Get", success, d, st.String()) } func (m *writeCacheMetrics) Delete(d time.Duration, success bool, st writecache.StorageType) { m.metrics.AddMethodDuration(m.shardID, "Delete", success, d, st.String()) if success { m.metrics.DecActualCount(m.shardID, st.String()) } } func (m *writeCacheMetrics) Put(d time.Duration, success bool, st writecache.StorageType) { m.metrics.AddMethodDuration(m.shardID, "Put", success, d, st.String()) if success { m.metrics.IncActualCount(m.shardID, st.String()) } } func (m *writeCacheMetrics) SetEstimateSize(db, fstree uint64) { m.metrics.SetEstimateSize(m.shardID, db, writecache.StorageTypeDB.String()) m.metrics.SetEstimateSize(m.shardID, fstree, writecache.StorageTypeFSTree.String()) } func (m *writeCacheMetrics) SetMode(mode mode.Mode) { m.metrics.SetMode(m.shardID, mode.String()) } func (m *writeCacheMetrics) SetActualCounters(db, fstree uint64) { m.metrics.SetActualCount(m.shardID, db, writecache.StorageTypeDB.String()) m.metrics.SetActualCount(m.shardID, fstree, writecache.StorageTypeFSTree.String()) } func (m *writeCacheMetrics) Flush(success bool, st writecache.StorageType) { m.metrics.IncOperationCounter(m.shardID, "Flush", metrics.NullBool{Bool: success, Valid: true}, st.String()) } func (m *writeCacheMetrics) Evict(st writecache.StorageType) { m.metrics.DecActualCount(m.shardID, st.String()) m.metrics.IncOperationCounter(m.shardID, "Evict", metrics.NullBool{}, st.String()) } func (m *writeCacheMetrics) Close() { m.metrics.Close(m.shardID) }