@@ -26,6 +26,9 @@ const (
2626 defaultHost = "localhost"
2727 defaultResolver = rpc
2828 defaultGracePeriod = 5
29+ defaultRetryBackoffMs = 1000
30+ defaultRetryBackoffMaxMs = 120000
31+ defaultFatalStatusCodes = "UNAUTHENTICATED,PERMISSION_DENIED"
2932
3033 rpc ResolverType = "rpc"
3134 inProcess ResolverType = "in-process"
@@ -45,6 +48,9 @@ const (
4548 flagdOfflinePathEnvironmentVariableName = "FLAGD_OFFLINE_FLAG_SOURCE_PATH"
4649 flagdTargetUriEnvironmentVariableName = "FLAGD_TARGET_URI"
4750 flagdGracePeriodVariableName = "FLAGD_RETRY_GRACE_PERIOD"
51+ flagdRetryBackoffMsVariableName = "FLAGD_RETRY_BACKOFF_MS"
52+ flagdRetryBackoffMaxMsVariableName = "FLAGD_RETRY_BACKOFF_MAX_MS"
53+ flagdFatalStatusCodesVariableName = "FLAGD_FATAL_STATUS_CODES"
4854)
4955
5056type ProviderConfiguration struct {
@@ -66,6 +72,9 @@ type ProviderConfiguration struct {
6672 CustomSyncProviderUri string
6773 GrpcDialOptionsOverride []grpc.DialOption
6874 RetryGracePeriod int
75+ RetryBackoffMs int
76+ RetryBackoffMaxMs int
77+ FatalStatusCodes []string
6978
7079 log logr.Logger
7180}
@@ -80,6 +89,9 @@ func newDefaultConfiguration(log logr.Logger) *ProviderConfiguration {
8089 Resolver : defaultResolver ,
8190 Tls : defaultTLS ,
8291 RetryGracePeriod : defaultGracePeriod ,
92+ RetryBackoffMs : defaultRetryBackoffMs ,
93+ RetryBackoffMaxMs : defaultRetryBackoffMaxMs ,
94+ FatalStatusCodes : strings .Split (defaultFatalStatusCodes , "," ),
8395 }
8496
8597 p .updateFromEnvVar ()
@@ -130,6 +142,7 @@ func validateProviderConfiguration(p *ProviderConfiguration) error {
130142
131143// updateFromEnvVar is a utility to update configurations based on current environment variables
132144func (cfg * ProviderConfiguration ) updateFromEnvVar () {
145+
133146 portS := os .Getenv (flagdPortEnvironmentVariableName )
134147 if portS != "" {
135148 port , err := strconv .Atoi (portS )
@@ -159,17 +172,7 @@ func (cfg *ProviderConfiguration) updateFromEnvVar() {
159172 cfg .CertPath = certificatePath
160173 }
161174
162- if maxCacheSizeS := os .Getenv (flagdMaxCacheSizeEnvironmentVariableName ); maxCacheSizeS != "" {
163- maxCacheSizeFromEnv , err := strconv .Atoi (maxCacheSizeS )
164- if err != nil {
165- cfg .log .Error (err ,
166- fmt .Sprintf ("invalid env config for %s provided, using default value: %d" ,
167- flagdMaxCacheSizeEnvironmentVariableName , defaultMaxCacheSize ,
168- ))
169- } else {
170- cfg .MaxCacheSize = maxCacheSizeFromEnv
171- }
172- }
175+ cfg .MaxCacheSize = getIntFromEnvVarOrDefault (flagdMaxCacheSizeEnvironmentVariableName , defaultMaxCacheSize , cfg .log )
173176
174177 if cacheValue := os .Getenv (flagdCacheEnvironmentVariableName ); cacheValue != "" {
175178 switch cache .Type (cacheValue ) {
@@ -185,18 +188,8 @@ func (cfg *ProviderConfiguration) updateFromEnvVar() {
185188 }
186189 }
187190
188- if maxEventStreamRetriesS := os .Getenv (
189- flagdMaxEventStreamRetriesEnvironmentVariableName ); maxEventStreamRetriesS != "" {
190-
191- maxEventStreamRetries , err := strconv .Atoi (maxEventStreamRetriesS )
192- if err != nil {
193- cfg .log .Error (err ,
194- fmt .Sprintf ("invalid env config for %s provided, using default value: %d" ,
195- flagdMaxEventStreamRetriesEnvironmentVariableName , defaultMaxEventStreamRetries ))
196- } else {
197- cfg .EventStreamConnectionMaxAttempts = maxEventStreamRetries
198- }
199- }
191+ cfg .EventStreamConnectionMaxAttempts = getIntFromEnvVarOrDefault (
192+ flagdMaxEventStreamRetriesEnvironmentVariableName , defaultMaxEventStreamRetries , cfg .log )
200193
201194 if resolver := os .Getenv (flagdResolverEnvironmentVariableName ); resolver != "" {
202195 switch strings .ToLower (resolver ) {
@@ -227,17 +220,34 @@ func (cfg *ProviderConfiguration) updateFromEnvVar() {
227220 if targetUri := os .Getenv (flagdTargetUriEnvironmentVariableName ); targetUri != "" {
228221 cfg .TargetUri = targetUri
229222 }
230- if gracePeriod := os .Getenv (flagdGracePeriodVariableName ); gracePeriod != "" {
231- if seconds , err := strconv .Atoi (gracePeriod ); err == nil {
232- cfg .RetryGracePeriod = seconds
223+
224+ cfg .RetryGracePeriod = getIntFromEnvVarOrDefault (flagdGracePeriodVariableName , defaultGracePeriod , cfg .log )
225+ cfg .RetryBackoffMs = getIntFromEnvVarOrDefault (flagdRetryBackoffMsVariableName , defaultRetryBackoffMs , cfg .log )
226+ cfg .RetryBackoffMaxMs = getIntFromEnvVarOrDefault (flagdRetryBackoffMaxMsVariableName , defaultRetryBackoffMaxMs , cfg .log )
227+
228+ if fatalStatusCodes := os .Getenv (flagdFatalStatusCodesVariableName ); fatalStatusCodes != "" {
229+ cfg .FatalStatusCodes = strings .Split (fatalStatusCodes , "," )
230+ }
231+ }
232+
233+ // Helper
234+
235+ func getIntFromEnvVarOrDefault (envVarName string , defaultValue int , log logr.Logger ) int {
236+ if valueFromEnv := os .Getenv (envVarName ); valueFromEnv != "" {
237+ intValue , err := strconv .Atoi (valueFromEnv )
238+ if err != nil {
239+ log .Error (err ,
240+ fmt .Sprintf ("invalid env config for %s provided, using default value: %d" ,
241+ envVarName , defaultValue ,
242+ ))
233243 } else {
234- // Handle parsing error
235- cfg .log .Error (err , fmt .Sprintf ("invalid grace period '%s'" , gracePeriod ))
244+ return intValue
236245 }
237246 }
238-
247+ return defaultValue
239248}
240249
250+
241251// ProviderOptions
242252
243253type ProviderOption func (* ProviderConfiguration )
@@ -415,3 +425,25 @@ func WithRetryGracePeriod(gracePeriod int) ProviderOption {
415425 p .RetryGracePeriod = gracePeriod
416426 }
417427}
428+
429+ // WithRetryBackoffMs sets the initial backoff duration (in milliseconds) for retrying failed connections
430+ func WithRetryBackoffMs (retryBackoffMs int ) ProviderOption {
431+ return func (p * ProviderConfiguration ) {
432+ p .RetryBackoffMs = retryBackoffMs
433+ }
434+ }
435+
436+ // WithRetryBackoffMaxMs sets the maximum backoff duration (in milliseconds) for retrying failed connections
437+ func WithRetryBackoffMaxMs (retryBackoffMaxMs int ) ProviderOption {
438+ return func (p * ProviderConfiguration ) {
439+ p .RetryBackoffMaxMs = retryBackoffMaxMs
440+ }
441+ }
442+
443+ // WithFatalStatusCodes allows to set a list of gRPC status codes, which will cause streams to give up
444+ // and put the provider in a PROVIDER_FATAL state
445+ func WithFatalStatusCodes (fatalStatusCodes []string ) ProviderOption {
446+ return func (p * ProviderConfiguration ) {
447+ p .FatalStatusCodes = fatalStatusCodes
448+ }
449+ }
0 commit comments