Unistore: Only Shadow Search Traffic when running on modes > 0 (#110302)

* Unistore: Only Shadow Search Traffic when running on modes > 0

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>

---------

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>
This commit is contained in:
maicon
2025-09-01 16:14:53 -03:00
committed by GitHub
parent 2f769b0a62
commit fccf58add7
2 changed files with 131 additions and 10 deletions
+36 -6
View File
@@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/storage/legacysql/dualwrite"
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
)
@@ -38,6 +39,7 @@ var (
type DualWriter interface {
IsEnabled(schema.GroupResource) bool
ReadFromUnified(context.Context, schema.GroupResource) (bool, error)
Status(ctx context.Context, gr schema.GroupResource) (dualwrite.StorageStatus, error)
}
func NewSearchClient(dual DualWriter, gr schema.GroupResource, unifiedClient resourcepb.ResourceIndexClient,
@@ -99,6 +101,28 @@ func calculateMatchPercentage(legacyUIDs, unifiedUIDs map[string]struct{}) float
return float64(matches) / float64(len(legacyUIDs)) * 100.0
}
// If dual reader feature flag is enabled, and legacy is the main storage,
// and we are writing to unified (which means we are effectively dual writing),
// then make a background call to unified
func shouldMakeBackgroundCall(ctx context.Context, features featuremgmt.FeatureToggles, dual DualWriter, gr schema.GroupResource) (bool, error) {
unifiedIsMainStorage, err := dual.ReadFromUnified(ctx, gr)
if err != nil {
return false, err
}
status, err := dual.Status(ctx, gr)
if err != nil {
return false, err
}
res := features != nil &&
features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageSearchDualReaderEnabled) &&
!unifiedIsMainStorage &&
status.WriteUnified
return res, nil
}
func (s *searchWrapper) GetStats(ctx context.Context, in *resourcepb.ResourceStatsRequest,
opts ...grpc.CallOption) (*resourcepb.ResourceStatsResponse, error) {
client := s.legacyClient
@@ -110,9 +134,12 @@ func (s *searchWrapper) GetStats(ctx context.Context, in *resourcepb.ResourceSta
client = s.unifiedClient
}
// If dual reader feature flag is enabled, and legacy is the main storage,
// make a background call to unified
if s.features != nil && s.features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageSearchDualReaderEnabled) && !unified {
makeBackgroundCall, err := shouldMakeBackgroundCall(ctx, s.features, s.dual, s.groupResource)
if err != nil {
return nil, err
}
if makeBackgroundCall {
// Create background context with timeout but ignore parent cancelation
ctxBg := context.WithoutCancel(ctx)
@@ -143,9 +170,12 @@ func (s *searchWrapper) Search(ctx context.Context, in *resourcepb.ResourceSearc
client = s.unifiedClient
}
// If dual reader feature flag is enabled, and legacy is the main storage,
// make a background call to unified and compare results
if s.features != nil && s.features.IsEnabledGlobally(featuremgmt.FlagUnifiedStorageSearchDualReaderEnabled) && !unified {
makeBackgroundCall, err := shouldMakeBackgroundCall(ctx, s.features, s.dual, s.groupResource)
if err != nil {
return nil, err
}
if makeBackgroundCall {
// Get the legacy result first
legacyResponse, legacyErr := s.legacyClient.Search(ctx, in, opts...)
if legacyErr != nil {