@@ -14,6 +14,7 @@ import (
1414 "github.com/google/uuid"
1515 "github.com/launchdarkly/go-sdk-common/v3/ldcontext"
1616 "go.opentelemetry.io/otel/attribute"
17+ "go.opentelemetry.io/otel/metric"
1718 "go.opentelemetry.io/otel/trace"
1819 "go.uber.org/zap"
1920
5253 "Total bytes written to NFS" ,
5354 "Total writes to NFS" ,
5455 ))
56+ nfsCacheConcurrentReads = utils .Must (meter .Int64UpDownCounter (
57+ "orchestrator.storage.slab.nfs.read.concurrent" ,
58+ metric .WithDescription ("Number of NFS cache range readers currently open" ),
59+ metric .WithUnit ("{read}" ),
60+ ))
5561)
5662
5763type featureFlagsClient interface {
@@ -119,7 +125,7 @@ func (c *cachedSeekable) OpenRangeReader(ctx context.Context, off int64, length
119125 rc := io .ReadCloser (& fsRangeReadCloser {Reader : io .NewSectionReader (fp , 0 , length ), file : fp })
120126 rc = withSpan (rc , span )
121127
122- return rc , nil
128+ return withNFSGauge ( ctx , rc ) , nil
123129 }
124130
125131 if ! os .IsNotExist (err ) {
@@ -169,6 +175,26 @@ func (r *spanReadCloser) Close() error {
169175 return err
170176}
171177
178+ // nfsGaugeReadCloser wraps a reader and decrements the NFS concurrent reads
179+ // gauge on Close.
180+ type nfsGaugeReadCloser struct {
181+ io.ReadCloser
182+
183+ ctx context.Context //nolint:containedctx // needed for gauge decrement in Close
184+ }
185+
186+ func (r * nfsGaugeReadCloser ) Close () error {
187+ nfsCacheConcurrentReads .Add (r .ctx , - 1 )
188+
189+ return r .ReadCloser .Close ()
190+ }
191+
192+ func withNFSGauge (ctx context.Context , rc io.ReadCloser ) io.ReadCloser {
193+ nfsCacheConcurrentReads .Add (ctx , 1 )
194+
195+ return & nfsGaugeReadCloser {ReadCloser : rc , ctx : ctx }
196+ }
197+
172198// newCacheWriteThroughReader wraps a reader, buffering all data read through it.
173199// On Close, it asynchronously writes the buffered data to the NFS cache only
174200// if the total bytes read match the expected length (to avoid caching truncated data).
0 commit comments