Procházet zdrojové kódy

Document the PinnableMetricsQuerier contract

State that no in-tree data source implements pinning yet, and spell out
the contract: the pinned view serves every query from the state at Pin
time until release, release is called exactly once after all queries
complete, and Pin may be called concurrently. Replace the empty release
closures with a documented noRelease function.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: peatey <warwick@automatic.systems>
peatey před 18 hodinami
rodič
revize
d91a2c1ca3
1 změnil soubory, kde provedl 21 přidání a 6 odebrání
  1. 21 6
      core/pkg/source/pin.go

+ 21 - 6
core/pkg/source/pin.go

@@ -6,26 +6,41 @@ package source
 // Computations that issue many queries for one window (allocation, assets, kube model) pin the querier
 // Computations that issue many queries for one window (allocation, assets, kube model) pin the querier
 // once and issue every query through the pinned view, so that all results come from one consistent
 // once and issue every query through the pinned view, so that all results come from one consistent
 // state of the data rather than a mix of states from before and after an update.
 // state of the data rather than a mix of states from before and after an update.
+//
+// No in-tree data source implements this today: the Prometheus and collector sources are unaffected.
+// It is intended for data sources that replace their state wholesale, such as an adapter serving
+// immutable snapshots.
 type PinnableMetricsQuerier interface {
 type PinnableMetricsQuerier interface {
 	MetricsQuerier
 	MetricsQuerier
 
 
-	// Pin returns a MetricsQuerier bound to the current state of the data, and a release function
-	// which must be called once the pinned querier is no longer used. The pinned querier must remain
-	// valid until released, even if the underlying data is updated in the meantime.
+	// Pin returns a MetricsQuerier bound to the current state of the data, and a release function.
+	//
+	// Contract:
+	//   - The pinned querier must serve every query from the state current at the time of Pin, and
+	//     keep that view valid until release is called, even if the underlying data is updated.
+	//   - Callers call release exactly once, after every query issued through the pinned querier has
+	//     completed. Implementations must make release safe to call exactly once; the pinned querier
+	//     must not be used after release.
+	//   - Pin may be called concurrently; each call returns an independent pinned view.
 	Pin() (MetricsQuerier, func())
 	Pin() (MetricsQuerier, func())
 }
 }
 
 
+// noRelease is the release function for a querier that was not pinned.
+func noRelease() {
+	// nothing was pinned, so there is nothing to release
+}
+
 // PinMetrics pins the querier if it implements PinnableMetricsQuerier. Otherwise it returns the querier
 // PinMetrics pins the querier if it implements PinnableMetricsQuerier. Otherwise it returns the querier
 // unchanged and a no-op release function.
 // unchanged and a no-op release function.
 func PinMetrics(q MetricsQuerier) (MetricsQuerier, func()) {
 func PinMetrics(q MetricsQuerier) (MetricsQuerier, func()) {
 	if p, ok := q.(PinnableMetricsQuerier); ok {
 	if p, ok := q.(PinnableMetricsQuerier); ok {
 		pinned, release := p.Pin()
 		pinned, release := p.Pin()
 		if release == nil {
 		if release == nil {
-			release = func() {}
+			release = noRelease
 		}
 		}
 		return pinned, release
 		return pinned, release
 	}
 	}
-	return q, func() {}
+	return q, noRelease
 }
 }
 
 
 // PinDataSource returns a data source whose Metrics() always returns the same pinned querier, for use
 // PinDataSource returns a data source whose Metrics() always returns the same pinned querier, for use
@@ -37,7 +52,7 @@ func PinMetrics(q MetricsQuerier) (MetricsQuerier, func()) {
 func PinDataSource(ds OpenCostDataSource) (OpenCostDataSource, func()) {
 func PinDataSource(ds OpenCostDataSource) (OpenCostDataSource, func()) {
 	q := ds.Metrics()
 	q := ds.Metrics()
 	if _, ok := q.(PinnableMetricsQuerier); !ok {
 	if _, ok := q.(PinnableMetricsQuerier); !ok {
-		return ds, func() {}
+		return ds, noRelease
 	}
 	}
 
 
 	pinned, release := PinMetrics(q)
 	pinned, release := PinMetrics(q)