From e1cde0f2d985eb2bb2ed92d066a6f9a8680f6720 Mon Sep 17 00:00:00 2001 From: "grafana-delivery-bot[bot]" <132647405+grafana-delivery-bot[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:49:35 +0000 Subject: [PATCH] [v11.4.x] Plugin Metrics: Eliminate data race in plugin metrics middleware (#100077) Plugin Metrics: Eliminate data race in plugin metrics middleware (#99396) fix: eliminate data race in plugin metrics middleware A data race was detected when multiple goroutines accessed the `MetricsMiddleware` simultaneously. The race occurred because a single `MetricsMiddleware` instance was being shared across goroutines while its `BaseHandler` field was being modified during middleware chain setup. Fix by creating a new `MetricsMiddleware` instance for each middleware chain, while safely sharing the thread-safe Prometheus metrics and plugin registry. This maintains proper metrics collection while eliminating the mutable shared state that caused the race condition. Original error was detected here: ``` WARNING: DATA RACE Read at 0x00c0039c0790 by goroutine 4486: github.com/grafana/grafana-plugin-sdk-go/backend.(*ErrorSourceMiddleware).CallResource() /Users/clord/src/grafana/irm-devstack/.devenv/state/go/pkg/mod/github.com/grafana/grafana-plugin-sdk-go@v0.261.0/backend/error_source_middleware.go:93 +0x40 github.com/grafana/grafana-plugin-sdk-go/backend.BaseHandler.CallResource() ... ``` (cherry picked from commit e74cf72d9902f8451f4f8e78fe36cf82cce71d53) Co-authored-by: Christopher Lord --- .../clientmiddleware/metrics_middleware.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go b/pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go index 29e7b1ec998..840257ea8de 100644 --- a/pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go +++ b/pkg/services/pluginsintegration/clientmiddleware/metrics_middleware.go @@ -76,10 +76,13 @@ func newMetricsMiddleware(promRegisterer prometheus.Registerer, pluginRegistry r // NewMetricsMiddleware returns a new MetricsMiddleware. func NewMetricsMiddleware(promRegisterer prometheus.Registerer, pluginRegistry registry.Service) backend.HandlerMiddleware { - imw := newMetricsMiddleware(promRegisterer, pluginRegistry) + metrics := newMetricsMiddleware(promRegisterer, pluginRegistry) return backend.HandlerMiddlewareFunc(func(next backend.Handler) backend.Handler { - imw.BaseHandler = backend.NewBaseHandler(next) - return imw + return &MetricsMiddleware{ + BaseHandler: backend.NewBaseHandler(next), + pluginMetrics: metrics.pluginMetrics, + pluginRegistry: metrics.pluginRegistry, + } }) }