@@ -4,17 +4,43 @@ import (
4
4
"time"
5
5
)
6
6
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
+
7
24
// Config provides configuration options for hitless upgrades.
8
25
type 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
13
33
14
34
// 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")
18
44
EndpointType string
19
45
20
46
// RelaxedTimeout is the concrete timeout value to use during
@@ -70,17 +96,17 @@ type Config struct {
70
96
// DefaultConfig returns a Config with sensible defaults.
71
97
func DefaultConfig () * Config {
72
98
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
81
107
PostHandoffRelaxedDuration : 10 * time .Second ,
82
- ScaleDownDelay : 2 * time .Second ,
83
- LogLevel : 1 ,
108
+ ScaleDownDelay : 2 * time .Second ,
109
+ LogLevel : 1 ,
84
110
}
85
111
}
86
112
@@ -111,15 +137,25 @@ func (c *Config) Validate() error {
111
137
return ErrInvalidLogLevel
112
138
}
113
139
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
114
151
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 ,
121
158
}
122
-
123
159
if ! validEndpointTypes [c .EndpointType ] {
124
160
return ErrInvalidEndpointType
125
161
}
@@ -142,9 +178,19 @@ func (c *Config) ApplyDefaultsWithPoolSize(poolSize int) *Config {
142
178
}
143
179
144
180
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
148
194
}
149
195
150
196
// Apply defaults for duration fields (zero means not set)
0 commit comments