From ba45719ce8df31a93157be24457dc2fdefb0c9eb Mon Sep 17 00:00:00 2001 From: Binh Nguyen Date: Fri, 24 Jul 2026 15:47:26 +0700 Subject: [PATCH] feat(operator): make the reconcile resync interval configurable The controller's ResyncInterval was hardcoded to 30s, so operators could not tune how often every RedisFailover is periodically re-reconciled. Add a --resync-period duration flag (default 30s) plumbed through Config.ResyncPeriod; the factory falls back to the 30s default when it is left unset. Refs upstream spotahome/redis-operator#661. --- README.md | 8 ++++++++ cmd/utils/flags.go | 4 ++++ operator/redisfailover/config.go | 5 +++++ operator/redisfailover/factory.go | 11 ++++++++--- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cdbf1dcae..68c4c53d8 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Redis Operator creates/configures/manages redis-failovers atop Kubernetes. - [Using kustomize](#using-kustomize) - [Usage](#usage) - [Reducing update churn (`--enable-hash`)](#reducing-update-churn---enable-hash) + - [Reconcile interval (`--resync-period`)](#reconcile-interval---resync-period) - [Persistence](#persistence) - [NodeAffinity and Tolerations](#nodeaffinity-and-tolerations) - [Topology Spread Contraints](#topology-spread-contraints) @@ -166,6 +167,13 @@ sync, because the operator's *desired* object is unchanged and so its hash still trading the operator's self-healing of manual drift for far fewer API writes. The flag is **off by default**, so upgrading changes nothing until you opt in. +### Reconcile interval (`--resync-period`) + +Beyond reacting to change events, the operator re-reconciles every `RedisFailover` on a fixed +interval so it can recover from missed events and correct drift. This defaults to `30s` and can be +tuned with `--resync-period` (any Go duration, e.g. `--resync-period=1m`). Larger values reduce API +load at the cost of slower periodic healing; smaller values react faster but poll more often. + ### Persistence The operator has the ability of add persistence to Redis data. By default an `emptyDir` will be used, so the data is not saved. diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 81e984c44..b43969618 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -5,6 +5,7 @@ import ( "fmt" "path/filepath" "regexp" + "time" "github.com/dnse-tech/redis-operator/operator/redisfailover" "k8s.io/client-go/util/homedir" @@ -23,6 +24,7 @@ type CMDFlags struct { Concurrency int LogLevel string EnableObjectHashing bool + ResyncPeriod time.Duration } // Init initializes and parse the flags @@ -43,6 +45,7 @@ func (c *CMDFlags) Init() { // Off by default: skipping unchanged writes also stops the operator from // correcting resources edited by hand, so opting in is a deliberate choice. flag.BoolVar(&c.EnableObjectHashing, "enable-hash", false, "Skip updating owned resources when they already match the desired state") + flag.DurationVar(&c.ResyncPeriod, "resync-period", 30*time.Second, "How often every RedisFailover is re-reconciled even without a change event") // Parse flags flag.Parse() @@ -58,5 +61,6 @@ func (c *CMDFlags) ToRedisOperatorConfig() redisfailover.Config { MetricsPath: c.MetricsPath, Concurrency: c.Concurrency, SupportedNamespacesRegex: c.SupportedNamespacesRegex, + ResyncPeriod: c.ResyncPeriod, } } diff --git a/operator/redisfailover/config.go b/operator/redisfailover/config.go index 1cd2ba0d4..b9c2ee37e 100644 --- a/operator/redisfailover/config.go +++ b/operator/redisfailover/config.go @@ -1,9 +1,14 @@ package redisfailover +import "time" + // Config is the configuration for the redis operator. type Config struct { ListenAddress string MetricsPath string Concurrency int SupportedNamespacesRegex string + // ResyncPeriod is how often every RedisFailover is re-reconciled even + // without a change event. Zero falls back to the built-in default. + ResyncPeriod time.Duration } diff --git a/operator/redisfailover/factory.go b/operator/redisfailover/factory.go index 2710002e0..ff52689f4 100644 --- a/operator/redisfailover/factory.go +++ b/operator/redisfailover/factory.go @@ -23,9 +23,9 @@ import ( ) const ( - resync = 30 * time.Second - operatorName = "redis-operator" - lockKey = "redis-failover-lease" + defaultResync = 30 * time.Second + operatorName = "redis-operator" + lockKey = "redis-failover-lease" ) // New will create an operator that is responsible of managing all the required stuff @@ -40,6 +40,11 @@ func New(cfg Config, k8sService k8s.Services, k8sClient kubernetes.Interface, lo rfHandler := NewRedisFailoverHandler(cfg, rfService, rfChecker, rfHealer, k8sService, kooperMetricsRecorder, logger) rfRetriever := NewRedisFailoverRetriever(cfg, k8sService) + resync := cfg.ResyncPeriod + if resync <= 0 { + resync = defaultResync + } + kooperLogger := kooperlogger{Logger: logger.WithField("operator", "redisfailover")} // Leader election service. leSVC, err := leaderelection.NewDefault(lockKey, lockNamespace, k8sClient, kooperLogger)