@@ -4,17 +4,43 @@ import (
44 "time"
55)
66
7+ // Constants for maintenance push notifications modes
8+ const (
9+ MaintNotificationsDisabled = "disabled" // Client doesn't send CLIENT MAINT_NOTIFICATIONS ON command
10+ MaintNotificationsEnabled = "enabled" // Client forcefully sends command, interrupts connection on error
11+ MaintNotificationsAuto = "auto" // Client tries to send command, disables feature on error
12+ )
13+
14+ // Constants for endpoint types
15+ const (
16+ EndpointTypeAuto = "auto" // Auto-detect based on connection
17+ EndpointTypeInternalIP = "internal-ip" // Internal IP address
18+ EndpointTypeInternalFQDN = "internal-fqdn" // Internal FQDN
19+ EndpointTypeExternalIP = "external-ip" // External IP address
20+ EndpointTypeExternalFQDN = "external-fqdn" // External FQDN
21+ EndpointTypeNone = "none" // No endpoint (reconnect with current config)
22+ )
23+
724// Config provides configuration options for hitless upgrades.
825type Config struct {
9- // Enabled controls whether hitless upgrades are enabled.
10- // Requires RESP3 protocol for push notifications.
11- // Default: false
12- Enabled bool
26+ // Enabled controls how client maintenance notifications are handled.
27+ // Valid values: MaintNotificationsDisabled, MaintNotificationsEnabled, MaintNotificationsAuto
28+ // - disabled: The client doesn't send CLIENT MAINT_NOTIFICATIONS ON command
29+ // - enabled: The client forcefully sends the command, interrupts connection on error
30+ // - auto: The client tries to send the command, disables feature on error
31+ // Default: MaintNotificationsAuto ("auto")
32+ Enabled string
1333
1434 // EndpointType specifies the type of endpoint to request in MOVING notifications.
15- // Valid values: "internal-ip", "internal-fqdn", "external-ip", "external-fqdn", "none"
16- // If empty, the client will auto-detect based on connection settings.
17- // Default: "" (auto-detect)
35+ // Valid values: EndpointTypeAuto, EndpointTypeInternalIP, EndpointTypeInternalFQDN,
36+ // EndpointTypeExternalIP, EndpointTypeExternalFQDN, EndpointTypeNone
37+ // - auto: Auto-detect based on connection (private IP → internal, TLS → FQDN)
38+ // - internal-ip: Enforce requesting the internal IP
39+ // - internal-fqdn: Enforce requesting the internal FQDN
40+ // - external-ip: Enforce requesting the external IP address
41+ // - external-fqdn: Enforce requesting the external FQDN
42+ // - none: Request null endpoint (reconnect based on current config)
43+ // Default: EndpointTypeAuto ("auto")
1844 EndpointType string
1945
2046 // RelaxedTimeout is the concrete timeout value to use during
@@ -70,17 +96,17 @@ type Config struct {
7096// DefaultConfig returns a Config with sensible defaults.
7197func DefaultConfig () * Config {
7298 return & Config {
73- Enabled : false ,
74- EndpointType : "" , // Auto-detect
75- RelaxedTimeout : 30 * time .Second ,
76- RelaxedTimeoutDuration : 30 * time .Second ,
77- HandoffTimeout : 15 * time .Second ,
78- MinWorkers : 0 , // Auto-calculated based on pool size
79- MaxWorkers : 0 , // Auto-calculated based on pool size
80- HandoffQueueSize : 0 , // Auto-calculated based on max workers
99+ Enabled : MaintNotificationsAuto , // Enable by default for Redis Cloud
100+ EndpointType : EndpointTypeAuto , // Auto-detect based on connection
101+ RelaxedTimeout : 30 * time .Second ,
102+ RelaxedTimeoutDuration : 30 * time .Second ,
103+ HandoffTimeout : 15 * time .Second ,
104+ MinWorkers : 0 , // Auto-calculated based on pool size
105+ MaxWorkers : 0 , // Auto-calculated based on pool size
106+ HandoffQueueSize : 0 , // Auto-calculated based on max workers
81107 PostHandoffRelaxedDuration : 10 * time .Second ,
82- ScaleDownDelay : 2 * time .Second ,
83- LogLevel : 1 ,
108+ ScaleDownDelay : 2 * time .Second ,
109+ LogLevel : 1 ,
84110 }
85111}
86112
@@ -111,15 +137,25 @@ func (c *Config) Validate() error {
111137 return ErrInvalidLogLevel
112138 }
113139
140+ // Validate Enabled (maintenance notifications mode)
141+ validMaintNotifications := map [string ]bool {
142+ MaintNotificationsDisabled : true ,
143+ MaintNotificationsEnabled : true ,
144+ MaintNotificationsAuto : true ,
145+ }
146+ if ! validMaintNotifications [c .Enabled ] {
147+ return ErrInvalidMaintNotifications
148+ }
149+
150+ // Validate EndpointType
114151 validEndpointTypes := map [string ]bool {
115- "" : true , // Auto-detect
116- "internal-ip" : true ,
117- "internal-fqdn" : true ,
118- "external-ip" : true ,
119- "external-fqdn" : true ,
120- "none" : true ,
152+ EndpointTypeAuto : true ,
153+ EndpointTypeInternalIP : true ,
154+ EndpointTypeInternalFQDN : true ,
155+ EndpointTypeExternalIP : true ,
156+ EndpointTypeExternalFQDN : true ,
157+ EndpointTypeNone : true ,
121158 }
122-
123159 if ! validEndpointTypes [c .EndpointType ] {
124160 return ErrInvalidEndpointType
125161 }
@@ -142,9 +178,19 @@ func (c *Config) ApplyDefaultsWithPoolSize(poolSize int) *Config {
142178 }
143179
144180 defaults := DefaultConfig ()
145- result := & Config {
146- Enabled : c .Enabled , // boolean, no default needed
147- EndpointType : c .EndpointType , // string, empty is valid (auto-detect)
181+ result := & Config {}
182+
183+ // Apply defaults for string fields (empty means not set)
184+ if c .Enabled == "" {
185+ result .Enabled = defaults .Enabled
186+ } else {
187+ result .Enabled = c .Enabled
188+ }
189+
190+ if c .EndpointType == "" {
191+ result .EndpointType = defaults .EndpointType
192+ } else {
193+ result .EndpointType = c .EndpointType
148194 }
149195
150196 // Apply defaults for duration fields (zero means not set)
0 commit comments