@@ -12,8 +12,8 @@ import (
1212 "github.com/open-feature/flagd/core/pkg/sync/grpc"
1313 "github.com/open-feature/flagd/core/pkg/sync/grpc/credentials"
1414 httpSync "github.com/open-feature/flagd/core/pkg/sync/http"
15+ "github.com/open-feature/flagd/core/pkg/sync/internal/polling"
1516 "github.com/open-feature/flagd/core/pkg/sync/kubernetes"
16- "github.com/robfig/cron"
1717 "go.uber.org/zap"
1818 "gocloud.dev/blob"
1919 "k8s.io/client-go/dynamic"
@@ -110,19 +110,19 @@ func (sb *SyncBuilder) syncFromConfig(sourceConfig sync.SourceConfig, logger *lo
110110 return sb .newK8s (sourceConfig .URI , logger )
111111 case syncProviderHTTP :
112112 logger .Debug (fmt .Sprintf ("using remote sync-provider for: %s" , sourceConfig .URI ))
113- return httpSync . NewHTTP (sourceConfig , logger ), nil
113+ return sb . newHTTP (sourceConfig , logger )
114114 case syncProviderGrpc :
115115 logger .Debug (fmt .Sprintf ("using grpc sync-provider for: %s" , sourceConfig .URI ))
116116 return sb .newGRPC (sourceConfig , logger ), nil
117117 case syncProviderGcs :
118118 logger .Debug (fmt .Sprintf ("using blob sync-provider with gcs driver for: %s" , sourceConfig .URI ))
119- return sb .newGcs (sourceConfig , logger ), nil
119+ return sb .newGcs (sourceConfig , logger )
120120 case syncProviderAzblob :
121121 logger .Debug (fmt .Sprintf ("using blob sync-provider with azblob driver for: %s" , sourceConfig .URI ))
122122 return sb .newAzblob (sourceConfig , logger )
123123 case syncProviderS3 :
124124 logger .Debug (fmt .Sprintf ("using blob sync-provider with s3 driver for: %s" , sourceConfig .URI ))
125- return sb .newS3 (sourceConfig , logger ), nil
125+ return sb .newS3 (sourceConfig , logger )
126126
127127 default :
128128 return nil , fmt .Errorf ("invalid sync provider: %s, must be one of with " +
@@ -201,17 +201,38 @@ func (sb *SyncBuilder) newGRPC(config sync.SourceConfig, logger *logger.Logger)
201201 }
202202}
203203
204- func (sb * SyncBuilder ) newGcs (config sync.SourceConfig , logger * logger.Logger ) * blobSync.Sync {
204+ // defaultInterval returns the configured interval or 5 seconds if unset,
205+ // along with a validated poller.
206+ func newPoller (config sync.SourceConfig ) (uint32 , * polling.CronPoller , error ) {
207+ var interval uint32 = 5
208+ if config .Interval != 0 {
209+ interval = config .Interval
210+ }
211+ poller , err := polling .NewCronPoller (interval , config .IntervalSeed )
212+ if err != nil {
213+ return 0 , nil , err
214+ }
215+ return interval , poller , nil
216+ }
217+
218+ func (sb * SyncBuilder ) newHTTP (config sync.SourceConfig , logger * logger.Logger ) (* httpSync.Sync , error ) {
219+ interval , poller , err := newPoller (config )
220+ if err != nil {
221+ return nil , fmt .Errorf ("invalid http sync configuration: %w" , err )
222+ }
223+ return httpSync .NewHTTP (config , logger , poller , interval ), nil
224+ }
225+
226+ func (sb * SyncBuilder ) newGcs (config sync.SourceConfig , logger * logger.Logger ) (* blobSync.Sync , error ) {
205227 // Extract bucket uri and object name from the full URI:
206228 // gs://bucket/path/to/object results in gs://bucket/ as bucketUri and
207229 // path/to/object as an object name.
208230 bucketURI := regGcs .FindString (config .URI )
209231 objectName := regGcs .ReplaceAllString (config .URI , "" )
210232
211- // Defaults to 5 seconds if interval is not set.
212- var interval uint32 = 5
213- if config .Interval != 0 {
214- interval = config .Interval
233+ interval , poller , err := newPoller (config )
234+ if err != nil {
235+ return nil , fmt .Errorf ("invalid gcs sync configuration: %w" , err )
215236 }
216237
217238 return & blobSync.Sync {
@@ -225,8 +246,8 @@ func (sb *SyncBuilder) newGcs(config sync.SourceConfig, logger *logger.Logger) *
225246 zap .String ("sync" , "gcs" ),
226247 ),
227248 Interval : interval ,
228- Cron : cron . New () ,
229- }
249+ Poller : poller ,
250+ }, nil
230251}
231252
232253func (sb * SyncBuilder ) newAzblob (config sync.SourceConfig , logger * logger.Logger ) (* blobSync.Sync , error ) {
@@ -245,10 +266,9 @@ func (sb *SyncBuilder) newAzblob(config sync.SourceConfig, logger *logger.Logger
245266 bucketURI := regAzblob .FindString (config .URI )
246267 objectName := regAzblob .ReplaceAllString (config .URI , "" )
247268
248- // Defaults to 5 seconds if interval is not set.
249- var interval uint32 = 5
250- if config .Interval != 0 {
251- interval = config .Interval
269+ interval , poller , err := newPoller (config )
270+ if err != nil {
271+ return nil , fmt .Errorf ("invalid azblob sync configuration: %w" , err )
252272 }
253273
254274 return & blobSync.Sync {
@@ -262,21 +282,20 @@ func (sb *SyncBuilder) newAzblob(config sync.SourceConfig, logger *logger.Logger
262282 zap .String ("sync" , "azblob" ),
263283 ),
264284 Interval : interval ,
265- Cron : cron . New () ,
285+ Poller : poller ,
266286 }, nil
267287}
268288
269- func (sb * SyncBuilder ) newS3 (config sync.SourceConfig , logger * logger.Logger ) * blobSync.Sync {
289+ func (sb * SyncBuilder ) newS3 (config sync.SourceConfig , logger * logger.Logger ) ( * blobSync.Sync , error ) {
270290 // Extract bucket uri and object name from the full URI:
271291 // s3://bucket/path/to/object results in s3://bucket/ as bucketUri and
272292 // path/to/object as an object name.
273293 bucketURI := regS3 .FindString (config .URI )
274294 objectName := regS3 .ReplaceAllString (config .URI , "" )
275295
276- // Defaults to 5 seconds if interval is not set.
277- var interval uint32 = 5
278- if config .Interval != 0 {
279- interval = config .Interval
296+ interval , poller , err := newPoller (config )
297+ if err != nil {
298+ return nil , fmt .Errorf ("invalid s3 sync configuration: %w" , err )
280299 }
281300
282301 return & blobSync.Sync {
@@ -290,8 +309,8 @@ func (sb *SyncBuilder) newS3(config sync.SourceConfig, logger *logger.Logger) *b
290309 zap .String ("sync" , "s3" ),
291310 ),
292311 Interval : interval ,
293- Cron : cron . New () ,
294- }
312+ Poller : poller ,
313+ }, nil
295314}
296315
297316type IK8sClientBuilder interface {
0 commit comments