From ff977c37838991b57ee237137a8b2e38d48dc4b2 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:06 +0100 Subject: [PATCH 01/12] Fix return -> continue in UpdateCache to prevent goroutine death The UpdateCache goroutine used `return` instead of `continue` on error paths (empty database, query parse failure, table extraction failure). A single transient error would permanently kill the goroutine, stopping all server-response caching for the plugin's lifetime. Resolves #64. --- plugin/plugin.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin/plugin.go b/plugin/plugin.go index 9966483..c232b1d 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -245,7 +245,7 @@ func (p *Plugin) UpdateCache(ctx context.Context) { "Skipping cache") p.Logger.Debug("Consider setting the database name in the " + "plugin config or disabling the plugin if you don't need it") - return + continue } cacheKey := strings.Join([]string{server["remote"], database, string(request)}, ":") @@ -261,13 +261,13 @@ func (p *Plugin) UpdateCache(ctx context.Context) { query, err := postgres.GetQueryFromRequest(request) if err != nil { p.Logger.Debug("Failed to get query from request", "error", err) - return + continue } tables, err := postgres.GetTablesFromQuery(query) if err != nil { p.Logger.Debug("Failed to get tables from query", "error", err) - return + continue } // Cache the table(s) used in each cached request. This is used to invalidate From af63cfd30a951f68102fa2569517a984726345ea Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:06 +0100 Subject: [PATCH 02/12] Fix IsCacheNeeded to check parsed query instead of cache key IsCacheNeeded was called with the full cache key (server:db:request_bytes) instead of the actual SQL query string. Date/time function detection against raw binary bytes was unreliable. Now the query is parsed first via GetQueryFromRequest and uppercased before checking. --- plugin/plugin.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugin/plugin.go b/plugin/plugin.go index c232b1d..ffe5bcf 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -249,7 +249,17 @@ func (p *Plugin) UpdateCache(ctx context.Context) { } cacheKey := strings.Join([]string{server["remote"], database, string(request)}, ":") - if errorResponse == "" && rowDescription != "" && dataRow != nil && len(dataRow) > 0 && IsCacheNeeded(cacheKey) { + if errorResponse == "" && rowDescription != "" && dataRow != nil && len(dataRow) > 0 { + query, err := postgres.GetQueryFromRequest(request) + if err != nil { + p.Logger.Debug("Failed to get query from request", "error", err) + continue + } + + if !IsCacheNeeded(strings.ToUpper(query)) { + continue + } + // The request was successful and the response contains data. Cache the response. if err := p.RedisClient.Set(ctx, cacheKey, response, p.Expiry).Err(); err != nil { CacheMissesCounter.Inc() @@ -257,13 +267,6 @@ func (p *Plugin) UpdateCache(ctx context.Context) { } CacheSetsCounter.Inc() - // Cache the query as well. - query, err := postgres.GetQueryFromRequest(request) - if err != nil { - p.Logger.Debug("Failed to get query from request", "error", err) - continue - } - tables, err := postgres.GetTablesFromQuery(query) if err != nil { p.Logger.Debug("Failed to get tables from query", "error", err) From 8dd818642f51029b4ff456d1eb714c5823460d67 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:06 +0100 Subject: [PATCH 03/12] Fix ExitOnStartupError ordering and close(nil) panic in main.go Move config field assignments (including ExitOnStartupError) before the API client initialization block so the flag is set when first checked. Also guard the deferred channel close to prevent a panic when config is nil and the channel was never initialized. --- main.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/main.go b/main.go index c4adee0..2c64640 100644 --- a/main.go +++ b/main.go @@ -50,6 +50,12 @@ func main() { //nolint:nestif if cfg := cast.ToStringMap(plugin.PluginConfig["config"]); cfg != nil { + pluginInstance.Impl.RedisURL = cast.ToString(cfg["redisURL"]) + pluginInstance.Impl.Expiry = cast.ToDuration(cfg["expiry"]) + pluginInstance.Impl.DefaultDBName = cast.ToString(cfg["defaultDBName"]) + pluginInstance.Impl.ScanCount = cast.ToInt64(cfg["scanCount"]) + pluginInstance.Impl.ExitOnStartupError = cast.ToBool(cfg["exitOnStartupError"]) + metricsConfig := metrics.NewMetricsConfig(cfg) if metricsConfig != nil && metricsConfig.Enabled { go metrics.ExposeMetrics(metricsConfig, logger) @@ -80,12 +86,6 @@ func main() { pluginInstance.Impl.UpdateCacheChannel = make(chan *v1.Struct, cacheBufferSize) go pluginInstance.Impl.UpdateCache(context.Background()) - pluginInstance.Impl.RedisURL = cast.ToString(cfg["redisURL"]) - pluginInstance.Impl.Expiry = cast.ToDuration(cfg["expiry"]) - pluginInstance.Impl.DefaultDBName = cast.ToString(cfg["defaultDBName"]) - pluginInstance.Impl.ScanCount = cast.ToInt64(cfg["scanCount"]) - pluginInstance.Impl.ExitOnStartupError = cast.ToBool(cfg["exitOnStartupError"]) - redisConfig, err := redis.ParseURL(pluginInstance.Impl.RedisURL) if err != nil { logger.Error("Failed to parse Redis URL", "error", err) @@ -126,7 +126,9 @@ func main() { } } - defer close(pluginInstance.Impl.UpdateCacheChannel) + if pluginInstance.Impl.UpdateCacheChannel != nil { + defer close(pluginInstance.Impl.UpdateCacheChannel) + } goplugin.Serve(&goplugin.ServeConfig{ HandshakeConfig: goplugin.HandshakeConfig{ From 73148f58e1206e0e5c77f1d2d1214820ad77351c Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:07 +0100 Subject: [PATCH 04/12] Add CacheErrorsCounter, fix double-counting misses, and fix typos Introduce a dedicated CacheErrorsCounter to separate Redis operation failures from genuine cache misses. Previously CacheMissesCounter was incremented for SET/DEL/SCAN errors, making the metric unreliable. Also fix double-counting in OnTrafficFromClient where a single miss incremented CacheMissesCounter twice. Fix typos: cachedRespnseKey -> cachedResponseKey, DateFucntion -> DateFunction. --- plugin/metrics.go | 5 +++++ plugin/plugin.go | 24 +++++++++++------------- plugin/plugin_test.go | 4 ++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/plugin/metrics.go b/plugin/metrics.go index 2d2ef05..69f4ae6 100644 --- a/plugin/metrics.go +++ b/plugin/metrics.go @@ -63,4 +63,9 @@ var ( Name: "cache_scan_keys_total", Help: "The total number of cache scan keys", }) + CacheErrorsCounter = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: metrics.Namespace, + Name: "cache_errors_total", + Help: "The total number of Redis operation errors", + }) ) diff --git a/plugin/plugin.go b/plugin/plugin.go index ffe5bcf..dd79103 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -111,7 +111,7 @@ func (p *Plugin) OnTrafficFromClient( if database == "" { database, err = p.RedisClient.Get(ctx, client["remote"]).Result() if err != nil { - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() p.Logger.Debug("Failed to get cache", "error", err) } CacheGetsCounter.Inc() @@ -150,7 +150,6 @@ func (p *Plugin) OnTrafficFromClient( // Check if the query is cached. response, err := p.RedisClient.Get(ctx, cacheKey).Bytes() if err != nil { - CacheMissesCounter.Inc() p.Logger.Debug("Failed to get cached response", "error", err) } CacheGetsCounter.Inc() @@ -170,8 +169,7 @@ func (p *Plugin) OnTrafficFromClient( }).ToMap(), }) if err != nil { - CacheMissesCounter.Inc() - // This should never happen, but log the error just in case. + CacheErrorsCounter.Inc() p.Logger.Error("Failed to create signals", "error", err) } else { CacheHitsCounter.Inc() @@ -230,7 +228,7 @@ func (p *Plugin) UpdateCache(ctx context.Context) { if client != nil && client["remote"] != "" { database, err = p.RedisClient.Get(ctx, client["remote"]).Result() if err != nil { - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() p.Logger.Debug("Failed to get cached response", "error", err) } CacheGetsCounter.Inc() @@ -262,7 +260,7 @@ func (p *Plugin) UpdateCache(ctx context.Context) { // The request was successful and the response contains data. Cache the response. if err := p.RedisClient.Set(ctx, cacheKey, response, p.Expiry).Err(); err != nil { - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() p.Logger.Debug("Failed to set cache", "error", err) } CacheSetsCounter.Inc() @@ -279,7 +277,7 @@ func (p *Plugin) UpdateCache(ctx context.Context) { requestQueryCacheKey := strings.Join([]string{table, cacheKey}, ":") if err := p.RedisClient.Set( ctx, requestQueryCacheKey, "", p.Expiry).Err(); err != nil { - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() p.Logger.Debug("Failed to set cache", "error", err) } CacheSetsCounter.Inc() @@ -303,7 +301,7 @@ func (p *Plugin) OnClosed(ctx context.Context, req *v1.Struct) (*v1.Struct, erro if client != nil { if err := p.RedisClient.Del(ctx, client["remote"]).Err(); err != nil { p.Logger.Debug("Failed to delete cache", "error", err) - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() } p.Logger.Debug("Client closed", "client", client["remote"]) CacheDeletesCounter.Inc() @@ -349,7 +347,7 @@ func (p *Plugin) invalidateDML(ctx context.Context, query string) { for { scanResult := p.RedisClient.Scan(ctx, cursor, table+":*", p.ScanCount) if scanResult.Err() != nil { - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() p.Logger.Debug("Failed to scan keys", "error", scanResult.Err()) break } @@ -361,8 +359,8 @@ func (p *Plugin) invalidateDML(ctx context.Context, query string) { CacheScanKeysCounter.Add(float64(len(keys))) for _, tableKey := range keys { // Invalidate the cache for the table. - cachedRespnseKey := strings.TrimPrefix(tableKey, table+":") - pipeline.Del(ctx, cachedRespnseKey) + cachedResponseKey := strings.TrimPrefix(tableKey, table+":") + pipeline.Del(ctx, cachedResponseKey) // Invalidate the table cache key itself. pipeline.Del(ctx, tableKey) } @@ -379,7 +377,7 @@ func (p *Plugin) invalidateDML(ctx context.Context, query string) { for _, res := range result { if res.Err() != nil { - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() } else { CacheDeletesCounter.Inc() } @@ -419,7 +417,7 @@ func (p *Plugin) getDBFromStartupMessage( startupMsgParams["database"], time.Duration(0), ).Err(); err != nil { - CacheMissesCounter.Inc() + CacheErrorsCounter.Inc() p.Logger.Debug("Failed to set cache", "error", err) } CacheSetsCounter.Inc() diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index 3d39250..c89abce 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -25,7 +25,7 @@ func testQueryRequest() (string, []byte) { return query, queryBytes } -func testQueryRequestWithDateFucntion() (string, []byte) { +func testQueryRequestWithDateFunction() (string, []byte) { query := `SELECT user_id, username, @@ -243,7 +243,7 @@ func TestPluginDateFunctionInQuery(t *testing.T) { plugin.Impl.OnTrafficFromClient(context.Background(), clientRequest) // Test the plugin's OnTrafficFromServer method with a query request. - _, queryRequest := testQueryRequestWithDateFucntion() + _, queryRequest := testQueryRequestWithDateFunction() queryResponse, err := base64.StdEncoding.DecodeString("VAAAABsAAWlkAAAAQAQAAQAAABcABP////8AAEQAAAALAAEAAAABMUMAAAANU0VMRUNUIDEAWgAAAAVJ") assert.Nil(t, err) queryArgs := map[string]interface{}{ From 969b22cc5b54600b1ba2e8ac92bf815e6e5e85e6 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:07 +0100 Subject: [PATCH 05/12] Extract duplicated startup error handling into helper function Replace three copies of the ExitOnStartupError check + manual close + os.Exit(1) pattern with a single handleStartupError helper that accepts variadic io.Closer resources. Reduces boilerplate and ensures consistent behavior across all startup error paths. --- main.go | 58 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/main.go b/main.go index 2c64640..7e402b0 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "context" "flag" + "io" "log" "os" @@ -22,9 +23,25 @@ import ( "google.golang.org/grpc/credentials/insecure" ) +// handleStartupError logs an error and exits if ExitOnStartupError is set, +// closing any provided resources before exit. +func handleStartupError( + logger hclog.Logger, exitOnError bool, msg string, err error, closers ...io.Closer, +) { + logger.Error(msg, "error", err) + if exitOnError { + logger.Info("Exiting due to startup error") + for _, c := range closers { + if c != nil { + c.Close() + } + } + os.Exit(1) + } +} + func main() { sentryDSN := sdkConfig.GetEnv("SENTRY_DSN", "") - // Initialize Sentry SDK err := sentry.Init(sentry.ClientOptions{ Dsn: sentryDSN, TracesSampleRate: 1.0, @@ -33,7 +50,6 @@ func main() { log.Fatalf("Failed to initialize Sentry SDK: %s", err.Error()) } - // Parse command line flags, passed by GatewayD via the plugin config logLevel := flag.String("log-level", "info", "Log level") flag.Parse() @@ -61,26 +77,20 @@ func main() { go metrics.ExposeMetrics(metricsConfig, logger) } - // Initialize the API client to get proxies from GatewayD. apiGRPCAddress := cast.ToString(cfg["apiGRPCAddress"]) apiClientConn, err := grpc.NewClient( apiGRPCAddress, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil || apiClientConn == nil { - logger.Error("Failed to initialize API client", "error", err) - if pluginInstance.Impl.ExitOnStartupError { - logger.Info("Exiting due to startup error") - if apiClientConn != nil { - apiClientConn.Close() - } - os.Exit(1) - } + handleStartupError( + logger, pluginInstance.Impl.ExitOnStartupError, + "Failed to initialize API client", err, apiClientConn) } defer apiClientConn.Close() pluginInstance.Impl.APIClient = apiV1.NewGatewayDAdminAPIServiceClient(apiClientConn) cacheBufferSize := cast.ToUint(cfg["cacheBufferSize"]) if cacheBufferSize <= 0 { - cacheBufferSize = 100 // default value + cacheBufferSize = 100 } pluginInstance.Impl.UpdateCacheChannel = make(chan *v1.Struct, cacheBufferSize) @@ -88,29 +98,18 @@ func main() { redisConfig, err := redis.ParseURL(pluginInstance.Impl.RedisURL) if err != nil { - logger.Error("Failed to parse Redis URL", "error", err) - if pluginInstance.Impl.ExitOnStartupError { - logger.Info("Exiting due to startup error") - if apiClientConn != nil { - apiClientConn.Close() - } - os.Exit(1) //nolint:gocritic - } + handleStartupError( + logger, pluginInstance.Impl.ExitOnStartupError, + "Failed to parse Redis URL", err, apiClientConn) } pluginInstance.Impl.RedisClient = redis.NewClient(redisConfig) - // Ping the Redis server to check if it is available. _, err = pluginInstance.Impl.RedisClient.Ping(context.Background()).Result() if err != nil { - logger.Error("Failed to ping Redis server", "error", err) - if pluginInstance.Impl.ExitOnStartupError { - logger.Info("Exiting due to startup error") - if apiClientConn != nil { - apiClientConn.Close() - } - os.Exit(1) - } + handleStartupError( + logger, pluginInstance.Impl.ExitOnStartupError, + "Failed to ping Redis server", err, apiClientConn) } pluginInstance.Impl.PeriodicInvalidatorEnabled = cast.ToBool( @@ -120,7 +119,6 @@ func main() { pluginInstance.Impl.PeriodicInvalidatorInterval = cast.ToDuration( cfg["periodicInvalidatorInterval"]) - // Start the periodic invalidator. if pluginInstance.Impl.PeriodicInvalidatorEnabled { pluginInstance.Impl.PeriodicInvalidator() } From 2a7bfd4a2a8afcf4b3cd835f0f7c955c0bcbc4e7 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:07 +0100 Subject: [PATCH 06/12] Add explicit config validation with sensible defaults Previously cast.To* silently returned zero-values for invalid config. Now redisURL, expiry, and scanCount are validated with warnings and defaults applied when values are missing or invalid. --- main.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 7e402b0..cf732c9 100644 --- a/main.go +++ b/main.go @@ -66,11 +66,27 @@ func main() { //nolint:nestif if cfg := cast.ToStringMap(plugin.PluginConfig["config"]); cfg != nil { + pluginInstance.Impl.ExitOnStartupError = cast.ToBool(cfg["exitOnStartupError"]) + pluginInstance.Impl.RedisURL = cast.ToString(cfg["redisURL"]) + if pluginInstance.Impl.RedisURL == "" { + logger.Warn("redisURL is empty, defaulting to redis://localhost:6379") + pluginInstance.Impl.RedisURL = "redis://localhost:6379" + } + pluginInstance.Impl.Expiry = cast.ToDuration(cfg["expiry"]) + if pluginInstance.Impl.Expiry <= 0 { + logger.Warn("expiry is invalid or unset, defaulting to 1h") + pluginInstance.Impl.Expiry = cast.ToDuration("1h") + } + pluginInstance.Impl.DefaultDBName = cast.ToString(cfg["defaultDBName"]) + pluginInstance.Impl.ScanCount = cast.ToInt64(cfg["scanCount"]) - pluginInstance.Impl.ExitOnStartupError = cast.ToBool(cfg["exitOnStartupError"]) + if pluginInstance.Impl.ScanCount <= 0 { + logger.Warn("scanCount is invalid or unset, defaulting to 1000") + pluginInstance.Impl.ScanCount = 1000 + } metricsConfig := metrics.NewMetricsConfig(cfg) if metricsConfig != nil && metricsConfig.Enabled { From 1e08ee65f0fd4784c8ae746f81b2da530b757da8 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:08 +0100 Subject: [PATCH 07/12] Add config validation and graceful goroutine shutdown via WaitGroup Add a WaitGroup to the Plugin struct so the UpdateCache goroutine signals completion when the channel is closed, allowing the process to drain pending cache updates before exit. Tests updated to use the same mechanism. --- main.go | 14 ++++++++++---- plugin/plugin.go | 3 +++ plugin/plugin_test.go | 26 ++++++++------------------ 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/main.go b/main.go index cf732c9..9b399f6 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "io" "log" "os" + "sync" "github.com/gatewayd-io/gatewayd-plugin-cache/plugin" sdkConfig "github.com/gatewayd-io/gatewayd-plugin-sdk/config" @@ -61,7 +62,8 @@ func main() { }) pluginInstance := plugin.NewCachePlugin(plugin.Plugin{ - Logger: logger, + Logger: logger, + WaitGroup: &sync.WaitGroup{}, }) //nolint:nestif @@ -110,6 +112,7 @@ func main() { } pluginInstance.Impl.UpdateCacheChannel = make(chan *v1.Struct, cacheBufferSize) + pluginInstance.Impl.WaitGroup.Add(1) go pluginInstance.Impl.UpdateCache(context.Background()) redisConfig, err := redis.ParseURL(pluginInstance.Impl.RedisURL) @@ -140,9 +143,12 @@ func main() { } } - if pluginInstance.Impl.UpdateCacheChannel != nil { - defer close(pluginInstance.Impl.UpdateCacheChannel) - } + defer func() { + if pluginInstance.Impl.UpdateCacheChannel != nil { + close(pluginInstance.Impl.UpdateCacheChannel) + pluginInstance.Impl.WaitGroup.Wait() + } + }() goplugin.Serve(&goplugin.ServeConfig{ HandshakeConfig: goplugin.HandshakeConfig{ diff --git a/plugin/plugin.go b/plugin/plugin.go index dd79103..d3b939d 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -4,6 +4,7 @@ import ( "context" "encoding/base64" "strings" + "sync" "time" sdkAct "github.com/gatewayd-io/gatewayd-plugin-sdk/act" @@ -35,6 +36,7 @@ type Plugin struct { ExitOnStartupError bool UpdateCacheChannel chan *v1.Struct + WaitGroup *sync.WaitGroup // Periodic invalidator configuration. PeriodicInvalidatorEnabled bool @@ -193,6 +195,7 @@ func IsCacheNeeded(upperQuery string) bool { } func (p *Plugin) UpdateCache(ctx context.Context) { + defer p.WaitGroup.Done() for { serverResponse, ok := <-p.UpdateCacheChannel if !ok { diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index c89abce..a060b0f 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -76,15 +76,11 @@ func Test_Plugin(t *testing.T) { RedisURL: redisURL, RedisClient: redisClient, UpdateCacheChannel: updateCacheChannel, + WaitGroup: &sync.WaitGroup{}, }) - // Use a WaitGroup to wait for the goroutine to finish - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - p.Impl.UpdateCache(context.Background()) - }() + p.Impl.WaitGroup.Add(1) + go p.Impl.UpdateCache(context.Background()) assert.NotNil(t, p) @@ -178,9 +174,8 @@ func Test_Plugin(t *testing.T) { assert.NotNil(t, result) assert.Equal(t, result, resp) - // Close the channel and wait for the cache updater to return gracefully close(updateCacheChannel) - wg.Wait() + p.Impl.WaitGroup.Wait() // Check that the query and response was cached. cachedResponse, err := redisClient.Get( @@ -216,15 +211,11 @@ func TestPluginDateFunctionInQuery(t *testing.T) { RedisURL: redisURL, RedisClient: redisClient, UpdateCacheChannel: cacheUpdateChannel, + WaitGroup: &sync.WaitGroup{}, }) - // Use a WaitGroup to wait for the goroutine to finish. - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - plugin.Impl.UpdateCache(context.Background()) - }() + plugin.Impl.WaitGroup.Add(1) + go plugin.Impl.UpdateCache(context.Background()) // Test the plugin's OnTrafficFromClient method with a StartupMessage. clientArgs := map[string]interface{}{ @@ -262,9 +253,8 @@ func TestPluginDateFunctionInQuery(t *testing.T) { serverRequest, err := v1.NewStruct(queryArgs) plugin.Impl.OnTrafficFromServer(context.Background(), serverRequest) - // Close the channel and wait for the cache updater to return gracefully. close(cacheUpdateChannel) - wg.Wait() + plugin.Impl.WaitGroup.Wait() keys, _ := redisClient.Keys(context.Background(), "*").Result() assert.Equal(t, 1, len(keys)) // Only one key (representing the database name) should be present. From f96519da730d00ccbd70b6147f2e06032cd3fdfe Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:08 +0100 Subject: [PATCH 08/12] Update gatewayd-plugin-sdk to v0.4.4, gatewayd to v0.11.0, and all direct deps SDK v0.4.4 brings redis/go-redis/v9, go-plugin v1.7.0, pgx/v5 v5.8.0, grpc v1.79.1, and protobuf v1.36.11. Also updates miniredis v2.36.1, sentry v0.42.0, cast v1.10.0, testify v1.11.1, and prometheus v1.23.2 via make update-direct-deps. --- go.mod | 48 ++++++++++---------- go.sum | 135 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 93 insertions(+), 90 deletions(-) diff --git a/go.mod b/go.mod index 16f0c72..4372611 100644 --- a/go.mod +++ b/go.mod @@ -1,23 +1,23 @@ module github.com/gatewayd-io/gatewayd-plugin-cache -go 1.24 +go 1.24.0 require ( - github.com/alicebob/miniredis/v2 v2.35.0 - github.com/gatewayd-io/gatewayd v0.10.2 - github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.3 - github.com/getsentry/sentry-go v0.35.0 + github.com/alicebob/miniredis/v2 v2.36.1 + github.com/gatewayd-io/gatewayd v0.11.0 + github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.4 + github.com/getsentry/sentry-go v0.42.0 github.com/go-co-op/gocron v1.37.0 github.com/go-redis/redis/v8 v8.11.5 github.com/hashicorp/go-hclog v1.6.3 - github.com/hashicorp/go-plugin v1.6.3 - github.com/jackc/pgx/v5 v5.7.5 - github.com/prometheus/client_golang v1.23.0 - github.com/spf13/cast v1.9.2 - github.com/stretchr/testify v1.10.0 + github.com/hashicorp/go-plugin v1.7.0 + github.com/jackc/pgx/v5 v5.8.0 + github.com/prometheus/client_golang v1.23.2 + github.com/spf13/cast v1.10.0 + github.com/stretchr/testify v1.11.1 github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 - google.golang.org/grpc v1.74.2 - google.golang.org/protobuf v1.36.7 + google.golang.org/grpc v1.79.1 + google.golang.org/protobuf v1.36.11 ) require ( @@ -25,35 +25,37 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/expr-lang/expr v1.17.5 // indirect + github.com/expr-lang/expr v1.17.8 // indirect github.com/fatih/color v1.18.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.8 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/run v1.1.0 // indirect github.com/onsi/gomega v1.34.1 // indirect - github.com/pganalyze/pg_query_go/v6 v6.1.0 // indirect + github.com/pganalyze/pg_query_go/v6 v6.2.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.65.0 // indirect + github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.16.1 // indirect - github.com/redis/go-redis/v9 v9.12.0 // indirect + github.com/redis/go-redis/v9 v9.18.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect - github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/zerolog v1.34.0 // indirect github.com/tetratelabs/wazero v1.9.0 // indirect github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 // indirect github.com/wasilibs/wazero-helpers v0.0.0-20250123031827-cd30c44769bb // indirect github.com/yuin/gopher-lua v1.1.1 // indirect + go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/net v0.40.0 // indirect - golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.25.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 80bfea2..1e5ff98 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,13 @@ -github.com/alicebob/miniredis/v2 v2.35.0 h1:QwLphYqCEAo1eu1TqPRN2jgVMPBweeQcR21jeqDCONI= -github.com/alicebob/miniredis/v2 v2.35.0/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= +github.com/alicebob/miniredis/v2 v2.36.1 h1:Dvc5oAnNOr7BIfPn7tF269U8DvRW1dBG2D5n0WrfYMI= +github.com/alicebob/miniredis/v2 v2.36.1/go.mod h1:TcL7YfarKPGDAthEtl5NBeHZfeUQj6OXMm/+iu5cLMM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= -github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -17,8 +17,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/expr-lang/expr v1.17.5 h1:i1WrMvcdLF249nSNlpQZN1S6NXuW9WaOfF5tPi3aw3k= -github.com/expr-lang/expr v1.17.5/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= +github.com/expr-lang/expr v1.17.8 h1:W1loDTT+0PQf5YteHSTpju2qfUfNoBt4yw9+wOEU9VM= +github.com/expr-lang/expr v1.17.8/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= @@ -26,12 +26,12 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gatewayd-io/gatewayd v0.10.2 h1:UpBjJhhzx+mJpFPsnerQVGGDzWouSekgmhwzVgCgrTc= -github.com/gatewayd-io/gatewayd v0.10.2/go.mod h1:hyRUqTcby5tnc+UfysxLAni25ltJ+5GG9gFDlhEON5o= -github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.3 h1:ru5NvbZWMLjNUmb4G4BKlN8jARYp5f7Ijab4BdwNDr8= -github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.3/go.mod h1:Dmkpyfcwb4MIcJHHLs/xQrz9JUvUUmegqpoGS6kqSb0= -github.com/getsentry/sentry-go v0.35.0 h1:+FJNlnjJsZMG3g0/rmmP7GiKjQoUF5EXfEtBwtPtkzY= -github.com/getsentry/sentry-go v0.35.0/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE= +github.com/gatewayd-io/gatewayd v0.11.0 h1:2VxHNhR0tHmtPy45fRbWQIJWqJJBa3RaqmeMtqVqxtQ= +github.com/gatewayd-io/gatewayd v0.11.0/go.mod h1:GMMoWCYIcAG0r0RDKMdh4STMI9azp7GcC0b1MHEIr3A= +github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.4 h1:/XEYjRuboxDmv5u6k26H7jwaZ0OyOIS57OZ6IZnUphM= +github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.4/go.mod h1:ahFlwwQY2+1TaEyWaGorQR6sHtBVxiDpjdDGK6givN4= +github.com/getsentry/sentry-go v0.42.0 h1:eeFMACuZTbUQf90RE8dE4tXeSe4CZyfvR1MBL7RLEt8= +github.com/getsentry/sentry-go v0.42.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s= github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0= github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= @@ -43,33 +43,33 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.8 h1:NpbJl/eVbvrGE0MJ6X16X9SAifesl6Fwxg/YmCvubRI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.8/go.mod h1:mi7YA+gCzVem12exXy46ZespvGtX/lZmD/RLnQhVW7U= github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg= -github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0= +github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= +github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs= -github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= -github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= +github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo= +github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -102,8 +102,8 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/pganalyze/pg_query_go/v6 v6.1.0 h1:jG5ZLhcVgL1FAw4C/0VNQaVmX1SUJx71wBGdtTtBvls= -github.com/pganalyze/pg_query_go/v6 v6.1.0/go.mod h1:nvTHIuoud6e1SfrUaFwHqT0i4b5Nr+1rPWVds3B5+50= +github.com/pganalyze/pg_query_go/v6 v6.2.2 h1:O0L6zMC226R82RF3X5n0Ki6HjytDsoAzuzp4ATVAHNo= +github.com/pganalyze/pg_query_go/v6 v6.2.2/go.mod h1:Cn6+j4870kJz3iYNsb0VsNG04vpSWgEvBwc590J4qD0= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -111,27 +111,27 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc= -github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE= -github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= +github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/redis/go-redis/v9 v9.12.0 h1:XlVPGlflh4nxfhsNXPA8Qp6EmEfTo0rp8oaBzPipXnU= -github.com/redis/go-redis/v9 v9.12.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/redis/go-redis/v9 v9.18.0 h1:pMkxYPkEbMPwRdenAzUNyFNrDgHx9U+DrBabWNfSRQs= +github.com/redis/go-redis/v9 v9.18.0/go.mod h1:k3ufPphLU5YXwNTUcCRXGxUoF1fqxnhFQmscfkCoDA0= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= -github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= -github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -140,8 +140,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 h1:mJdDDPblDfPe7z7go8Dvv1AJQDI3eQ/5xith3q2mFlo= @@ -150,31 +150,33 @@ github.com/wasilibs/wazero-helpers v0.0.0-20250123031827-cd30c44769bb h1:gQ+ZV4w github.com/wasilibs/wazero-helpers v0.0.0-20250123031827-cd30c44769bb/go.mod h1:jMeV4Vpbi8osrE/pKUxRZkVaA0EX7NZN0A9/oRzgpgY= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 h1:qXafrlZL1WsJW5OokjraLLRURHiw0OzKHD/RNdspp4w= github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04/go.mod h1:FiwNQxz6hGoNFBC4nIx+CxZhI3nne5RmIOlT/MXcSD4= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= +go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= +go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= +go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= +go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= +go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= +go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= +go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= +go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= +go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -183,21 +185,20 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ= -google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A= -google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= +google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From ed4ea8ee5e23514f1c5047a20cc7967a68ca1ddf Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:08 +0100 Subject: [PATCH 09/12] Migrate from go-redis/redis/v8 to redis/go-redis/v9 Replace deprecated github.com/go-redis/redis/v8 with the maintained github.com/redis/go-redis/v9. Updated import paths in plugin.go, main.go, plugin_test.go, and the depguard config in .golangci.yaml. --- .golangci.yaml | 2 +- go.mod | 4 +--- go.sum | 14 -------------- main.go | 2 +- plugin/plugin.go | 2 +- plugin/plugin_test.go | 2 +- 6 files changed, 5 insertions(+), 21 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 061224d..155d2a5 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -35,7 +35,7 @@ linters-settings: - "github.com/prometheus/client_golang" - "github.com/hashicorp/go-plugin" - "github.com/hashicorp/go-hclog" - - "github.com/go-redis/redis/v8" + - "github.com/redis/go-redis/v9" - "github.com/getsentry/sentry-go" - "github.com/spf13/cast" - "github.com/go-co-op/gocron" diff --git a/go.mod b/go.mod index 4372611..c39df0a 100644 --- a/go.mod +++ b/go.mod @@ -8,11 +8,11 @@ require ( github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.4 github.com/getsentry/sentry-go v0.42.0 github.com/go-co-op/gocron v1.37.0 - github.com/go-redis/redis/v8 v8.11.5 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-plugin v1.7.0 github.com/jackc/pgx/v5 v5.8.0 github.com/prometheus/client_golang v1.23.2 + github.com/redis/go-redis/v9 v9.18.0 github.com/spf13/cast v1.10.0 github.com/stretchr/testify v1.11.1 github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04 @@ -35,13 +35,11 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/run v1.1.0 // indirect - github.com/onsi/gomega v1.34.1 // indirect github.com/pganalyze/pg_query_go/v6 v6.2.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.16.1 // indirect - github.com/redis/go-redis/v9 v9.18.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rs/zerolog v1.34.0 // indirect diff --git a/go.sum b/go.sum index 1e5ff98..a6453b8 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,6 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gatewayd-io/gatewayd v0.11.0 h1:2VxHNhR0tHmtPy45fRbWQIJWqJJBa3RaqmeMtqVqxtQ= github.com/gatewayd-io/gatewayd v0.11.0/go.mod h1:GMMoWCYIcAG0r0RDKMdh4STMI9azp7GcC0b1MHEIr3A= github.com/gatewayd-io/gatewayd-plugin-sdk v0.4.4 h1:/XEYjRuboxDmv5u6k26H7jwaZ0OyOIS57OZ6IZnUphM= @@ -40,8 +38,6 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= -github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= @@ -94,14 +90,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/pganalyze/pg_query_go/v6 v6.2.2 h1:O0L6zMC226R82RF3X5n0Ki6HjytDsoAzuzp4ATVAHNo= github.com/pganalyze/pg_query_go/v6 v6.2.2/go.mod h1:Cn6+j4870kJz3iYNsb0VsNG04vpSWgEvBwc590J4qD0= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -173,8 +163,6 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -204,8 +192,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 9b399f6..0e320a4 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,7 @@ import ( v1 "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin/v1" apiV1 "github.com/gatewayd-io/gatewayd/api/v1" "github.com/getsentry/sentry-go" - "github.com/go-redis/redis/v8" + "github.com/redis/go-redis/v9" "github.com/hashicorp/go-hclog" goplugin "github.com/hashicorp/go-plugin" "github.com/spf13/cast" diff --git a/plugin/plugin.go b/plugin/plugin.go index d3b939d..e8104d1 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -12,7 +12,7 @@ import ( sdkPlugin "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin" v1 "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin/v1" apiV1 "github.com/gatewayd-io/gatewayd/api/v1" - goRedis "github.com/go-redis/redis/v8" + goRedis "github.com/redis/go-redis/v9" "github.com/hashicorp/go-hclog" goplugin "github.com/hashicorp/go-plugin" "github.com/spf13/cast" diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index a060b0f..ab88cf5 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -11,7 +11,7 @@ import ( sdkAct "github.com/gatewayd-io/gatewayd-plugin-sdk/act" "github.com/gatewayd-io/gatewayd-plugin-sdk/logging" v1 "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin/v1" - "github.com/go-redis/redis/v8" + "github.com/redis/go-redis/v9" "github.com/hashicorp/go-hclog" pgproto3 "github.com/jackc/pgx/v5/pgproto3" "github.com/stretchr/testify/assert" From ac80d69d6b48c3515afb817616907a2558a140dd Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:15 +0100 Subject: [PATCH 10/12] Update CI actions to v4/v5, add govulncheck to test workflow Bump actions/checkout to v4, actions/setup-go to v5 (Node 20), and softprops/action-gh-release to v2. Add govulncheck step to the test workflow for security scanning. setup-go v5 includes built-in module caching. --- .github/workflows/release.yaml | 6 +++--- .github/workflows/test.yaml | 10 +++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f5157c5..8d5afa3 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -13,11 +13,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Go 1.24 - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: "1.24" cache: true @@ -27,7 +27,7 @@ jobs: run: | make build-release - name: Create release and add artifacts - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: | dist/*.tar.gz diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8bce6c6..c3dbbde 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -12,22 +12,26 @@ jobs: test: name: Test gatewayd-plugin-cache runs-on: ubuntu-latest - # Timeout after 5 minutes, to avoid hanging tests timeout-minutes: 5 steps: - name: Checkout 🛎️ - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go 🧑‍💻 - uses: actions/setup-go@v3 + uses: actions/setup-go@v5 with: go-version: "1.24" - name: Lint code issues 🚨 uses: golangci/golangci-lint-action@v6 + - name: Run govulncheck 🔒 + uses: golang/govulncheck-action@v1 + with: + go-version-input: "1.24" + - name: Run Go tests 🔬 run: go test -cover -covermode atomic -coverprofile=profile.cov -v ./... From 2eee5d4a7ebf9efef8593423cb033da3928514ab Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:13:15 +0100 Subject: [PATCH 11/12] Add tests for IsCacheNeeded, OnClosed, invalidateDML, and goroutine resilience - TestIsCacheNeeded: table-driven test covering all PostgreSQL date/time functions plus positive cases (SELECT, INSERT, empty) - TestOnClosed: verifies client-to-database key cleanup on connection close - TestOnClosedNilClient: verifies graceful handling of nil client - TestInvalidateDML: verifies INSERT invalidates cached SELECT responses and their table index keys - TestInvalidateDMLSelectIgnored: verifies SELECT queries don't trigger invalidation - TestUpdateCacheContinuesOnError: confirms the goroutine survives errors and processes subsequent messages (validates the return->continue fix) --- plugin/plugin_test.go | 195 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 194 insertions(+), 1 deletion(-) diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go index ab88cf5..5b9ff93 100644 --- a/plugin/plugin_test.go +++ b/plugin/plugin_test.go @@ -3,17 +3,19 @@ package plugin import ( "context" "encoding/base64" + "encoding/json" "os" "sync" "testing" + "time" miniredis "github.com/alicebob/miniredis/v2" sdkAct "github.com/gatewayd-io/gatewayd-plugin-sdk/act" "github.com/gatewayd-io/gatewayd-plugin-sdk/logging" v1 "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin/v1" - "github.com/redis/go-redis/v9" "github.com/hashicorp/go-hclog" pgproto3 "github.com/jackc/pgx/v5/pgproto3" + "github.com/redis/go-redis/v9" "github.com/stretchr/testify/assert" ) @@ -259,3 +261,194 @@ func TestPluginDateFunctionInQuery(t *testing.T) { keys, _ := redisClient.Keys(context.Background(), "*").Result() assert.Equal(t, 1, len(keys)) // Only one key (representing the database name) should be present. } + +func newTestPlugin(t *testing.T) (*CachePlugin, *redis.Client) { + t.Helper() + redisServer := miniredis.RunT(t) + redisURL := "redis://" + redisServer.Addr() + "/0" + redisConfig, _ := redis.ParseURL(redisURL) + redisClient := redis.NewClient(redisConfig) + + logger := hclog.New(&hclog.LoggerOptions{ + Level: logging.GetLogLevel("error"), + Output: os.Stdout, + }) + p := NewCachePlugin(Plugin{ + Logger: logger, + RedisURL: redisURL, + RedisClient: redisClient, + Expiry: time.Hour, + ScanCount: 1000, + UpdateCacheChannel: make(chan *v1.Struct, 10), + WaitGroup: &sync.WaitGroup{}, + }) + return p, redisClient +} + +func TestIsCacheNeeded(t *testing.T) { + tests := []struct { + name string + query string + want bool + }{ + {"plain SELECT", "SELECT * FROM USERS", true}, + {"contains NOW()", "SELECT NOW(), ID FROM USERS", false}, + {"contains CURRENT_DATE", "SELECT ID FROM USERS WHERE CREATED_AT >= CURRENT_DATE", false}, + {"contains CURRENT_TIMESTAMP", "SELECT CURRENT_TIMESTAMP", false}, + {"contains CLOCK_TIMESTAMP()", "SELECT CLOCK_TIMESTAMP()", false}, + {"contains LOCALTIME", "SELECT LOCALTIME", false}, + {"contains LOCALTIMESTAMP", "SELECT LOCALTIMESTAMP", false}, + {"contains AGE()", "SELECT AGE(TIMESTAMP '2001-04-10')", false}, + {"contains STATEMENT_TIMESTAMP", "SELECT STATEMENT_TIMESTAMP()", false}, + {"contains TIMEOFDAY", "SELECT TIMEOFDAY()", false}, + {"contains TRANSACTION_TIMESTAMP", "SELECT TRANSACTION_TIMESTAMP()", false}, + {"INSERT query", "INSERT INTO USERS VALUES (1)", true}, + {"empty query", "", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, IsCacheNeeded(tt.query)) + }) + } +} + +func TestOnClosed(t *testing.T) { + p, redisClient := newTestPlugin(t) + ctx := context.Background() + + // Simulate a stored client-to-database mapping. + redisClient.Set(ctx, "localhost:45320", "postgres", 0) + val := redisClient.Get(ctx, "localhost:45320").Val() + assert.Equal(t, "postgres", val) + + // Call OnClosed to clean up. + args := map[string]interface{}{ + "client": map[string]interface{}{ + "local": "localhost:15432", + "remote": "localhost:45320", + }, + } + req, err := v1.NewStruct(args) + assert.Nil(t, err) + + result, err := p.Impl.OnClosed(ctx, req) + assert.Nil(t, err) + assert.NotNil(t, result) + + // The client key should be deleted. + val = redisClient.Get(ctx, "localhost:45320").Val() + assert.Equal(t, "", val) +} + +func TestOnClosedNilClient(t *testing.T) { + p, _ := newTestPlugin(t) + ctx := context.Background() + + args := map[string]interface{}{} + req, err := v1.NewStruct(args) + assert.Nil(t, err) + + result, err := p.Impl.OnClosed(ctx, req) + assert.Nil(t, err) + assert.NotNil(t, result) +} + +func TestInvalidateDML(t *testing.T) { + p, redisClient := newTestPlugin(t) + ctx := context.Background() + + _, request := testQueryRequest() + cacheKey := "localhost:5432:postgres:" + string(request) + tableKey := "users:" + cacheKey + + // Pre-populate cache entries (simulating cached SELECT response + table index). + redisClient.Set(ctx, cacheKey, "cached-response-data", time.Hour) + redisClient.Set(ctx, tableKey, "", time.Hour) + + val := redisClient.Get(ctx, cacheKey).Val() + assert.Equal(t, "cached-response-data", val) + + // Build a base64-encoded query message for an INSERT query. + insertQuery := map[string]string{"String": "INSERT INTO users VALUES (1)"} + queryJSON, err := json.Marshal(insertQuery) + assert.Nil(t, err) + encodedQuery := base64.StdEncoding.EncodeToString(queryJSON) + + p.Impl.invalidateDML(ctx, encodedQuery) + + // Both the cached response and the table index key should be deleted. + val = redisClient.Get(ctx, cacheKey).Val() + assert.Equal(t, "", val) + val = redisClient.Get(ctx, tableKey).Val() + assert.Equal(t, "", val) +} + +func TestInvalidateDMLSelectIgnored(t *testing.T) { + p, redisClient := newTestPlugin(t) + ctx := context.Background() + + // Pre-populate a cache entry. + redisClient.Set(ctx, "test-key", "test-value", time.Hour) + + selectQuery := map[string]string{"String": "SELECT * FROM users"} + queryJSON, _ := json.Marshal(selectQuery) + encodedQuery := base64.StdEncoding.EncodeToString(queryJSON) + + p.Impl.invalidateDML(ctx, encodedQuery) + + // SELECT queries should not trigger invalidation. + val := redisClient.Get(ctx, "test-key").Val() + assert.Equal(t, "test-value", val) +} + +func TestUpdateCacheContinuesOnError(t *testing.T) { + p, redisClient := newTestPlugin(t) + ctx := context.Background() + + p.Impl.WaitGroup.Add(1) + go p.Impl.UpdateCache(ctx) + + // Send a message with empty database (should trigger continue, not kill goroutine). + badArgs := map[string]interface{}{ + "request": []byte{}, + "response": []byte{}, + "client": map[string]interface{}{ + "remote": "unknown:99999", + }, + "server": map[string]interface{}{ + "remote": "localhost:5432", + }, + } + badResp, _ := v1.NewStruct(badArgs) + p.Impl.UpdateCacheChannel <- badResp + + // Now send a valid message. If the goroutine survived, this will be processed. + _, request := testQueryRequest() + response, _ := base64.StdEncoding.DecodeString( + "VAAAABsAAWlkAAAAQAQAAQAAABcABP////8AAEQAAAALAAEAAAABMUMAAAANU0VMRUNUIDEAWgAAAAVJ") + + // Set up the database mapping so UpdateCache can find it. + redisClient.Set(ctx, "localhost:45320", "postgres", 0) + + goodArgs := map[string]interface{}{ + "request": request, + "response": response, + "client": map[string]interface{}{ + "remote": "localhost:45320", + }, + "server": map[string]interface{}{ + "remote": "localhost:5432", + }, + } + goodResp, _ := v1.NewStruct(goodArgs) + p.Impl.UpdateCacheChannel <- goodResp + + close(p.Impl.UpdateCacheChannel) + p.Impl.WaitGroup.Wait() + + // The valid message should have been cached (goroutine survived the error). + cachedResponse, err := redisClient.Get( + ctx, "localhost:5432:postgres:"+string(request)).Bytes() + assert.Nil(t, err) + assert.Equal(t, response, cachedResponse) +} From 106048030344db7341bd1944c235a7a646ea2aa2 Mon Sep 17 00:00:00 2001 From: Mostafa Moradian Date: Sat, 21 Feb 2026 22:16:37 +0100 Subject: [PATCH 12/12] Fix golangci-lint issues: import ordering and nestif complexity Sort imports alphabetically to satisfy gci linter. Reduce nestif complexity in UpdateCache by inverting the caching precondition into an early continue. --- main.go | 2 +- plugin/plugin.go | 62 +++++++++++++++++++++++++----------------------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/main.go b/main.go index 0e320a4..520638a 100644 --- a/main.go +++ b/main.go @@ -16,9 +16,9 @@ import ( v1 "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin/v1" apiV1 "github.com/gatewayd-io/gatewayd/api/v1" "github.com/getsentry/sentry-go" - "github.com/redis/go-redis/v9" "github.com/hashicorp/go-hclog" goplugin "github.com/hashicorp/go-plugin" + "github.com/redis/go-redis/v9" "github.com/spf13/cast" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" diff --git a/plugin/plugin.go b/plugin/plugin.go index e8104d1..346f2cf 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -12,9 +12,9 @@ import ( sdkPlugin "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin" v1 "github.com/gatewayd-io/gatewayd-plugin-sdk/plugin/v1" apiV1 "github.com/gatewayd-io/gatewayd/api/v1" - goRedis "github.com/redis/go-redis/v9" "github.com/hashicorp/go-hclog" goplugin "github.com/hashicorp/go-plugin" + goRedis "github.com/redis/go-redis/v9" "github.com/spf13/cast" "google.golang.org/grpc" ) @@ -250,41 +250,43 @@ func (p *Plugin) UpdateCache(ctx context.Context) { } cacheKey := strings.Join([]string{server["remote"], database, string(request)}, ":") - if errorResponse == "" && rowDescription != "" && dataRow != nil && len(dataRow) > 0 { - query, err := postgres.GetQueryFromRequest(request) - if err != nil { - p.Logger.Debug("Failed to get query from request", "error", err) - continue - } + if errorResponse != "" || rowDescription == "" || dataRow == nil || len(dataRow) == 0 { + continue + } - if !IsCacheNeeded(strings.ToUpper(query)) { - continue - } + query, err := postgres.GetQueryFromRequest(request) + if err != nil { + p.Logger.Debug("Failed to get query from request", "error", err) + continue + } + + if !IsCacheNeeded(strings.ToUpper(query)) { + continue + } + + // The request was successful and the response contains data. Cache the response. + if err := p.RedisClient.Set(ctx, cacheKey, response, p.Expiry).Err(); err != nil { + CacheErrorsCounter.Inc() + p.Logger.Debug("Failed to set cache", "error", err) + } + CacheSetsCounter.Inc() - // The request was successful and the response contains data. Cache the response. - if err := p.RedisClient.Set(ctx, cacheKey, response, p.Expiry).Err(); err != nil { + tables, err := postgres.GetTablesFromQuery(query) + if err != nil { + p.Logger.Debug("Failed to get tables from query", "error", err) + continue + } + + // Cache the table(s) used in each cached request. This is used to invalidate + // the cache when a rows is inserted, updated or deleted into that table. + for _, table := range tables { + requestQueryCacheKey := strings.Join([]string{table, cacheKey}, ":") + if err := p.RedisClient.Set( + ctx, requestQueryCacheKey, "", p.Expiry).Err(); err != nil { CacheErrorsCounter.Inc() p.Logger.Debug("Failed to set cache", "error", err) } CacheSetsCounter.Inc() - - tables, err := postgres.GetTablesFromQuery(query) - if err != nil { - p.Logger.Debug("Failed to get tables from query", "error", err) - continue - } - - // Cache the table(s) used in each cached request. This is used to invalidate - // the cache when a rows is inserted, updated or deleted into that table. - for _, table := range tables { - requestQueryCacheKey := strings.Join([]string{table, cacheKey}, ":") - if err := p.RedisClient.Set( - ctx, requestQueryCacheKey, "", p.Expiry).Err(); err != nil { - CacheErrorsCounter.Inc() - p.Logger.Debug("Failed to set cache", "error", err) - } - CacheSetsCounter.Inc() - } } } }