88 "os"
99 "slices"
1010 "sync"
11+ "time"
1112
1213 "github.com/go-git/go-billy/v5/osfs"
1314 "github.com/go-git/go-git/v5"
@@ -18,6 +19,7 @@ import (
1819 gitstorage "github.com/go-git/go-git/v5/storage"
1920 "github.com/go-git/go-git/v5/storage/filesystem"
2021 "github.com/go-git/go-git/v5/storage/memory"
22+
2123 "go.flipt.io/flipt/internal/containers"
2224 "go.flipt.io/flipt/internal/gitfs"
2325 "go.flipt.io/flipt/internal/storage"
@@ -139,6 +141,7 @@ func NewSnapshotStore(ctx context.Context, logger *zap.Logger, url string, opts
139141 baseRef : "main" ,
140142 referenceResolver : staticResolver (),
141143 }
144+
142145 containers .ApplyAll (store , opts ... )
143146
144147 store .logger = store .logger .With (zap .String ("ref" , store .baseRef ))
@@ -335,14 +338,20 @@ func (s *SnapshotStore) listRemoteRefs(ctx context.Context) (map[string]struct{}
335338// HEAD updates to a new revision, it builds a snapshot and updates it
336339// on the store.
337340func (s * SnapshotStore ) update (ctx context.Context ) (bool , error ) {
341+ syncStart := time .Now ()
338342 updated , fetchErr := s .fetch (ctx , s .snaps .References ())
339343
344+ flagsFetched := int64 (0 )
345+ var errs []error
346+
340347 if ! updated && fetchErr == nil {
348+ // No update and no error: record metrics for a successful no-change sync
349+ duration := time .Since (syncStart )
350+ observeSync (ctx , duration , 0 , true )
341351 return false , nil
342352 }
343353
344- // If we can't fetch, we need to check if the remote refs have changed
345- // and remove any references that are no longer present
354+ // If fetchErr exists, try cleaning up refs but do not declare full failure yet
346355 if fetchErr != nil {
347356 remoteRefs , listErr := s .listRemoteRefs (ctx )
348357 if listErr != nil {
@@ -361,23 +370,37 @@ func (s *SnapshotStore) update(ctx context.Context) (bool, error) {
361370 }
362371 }
363372 }
364- }
365-
366- var errs []error
367- if fetchErr != nil {
368373 errs = append (errs , fetchErr )
369374 }
375+
376+ // Try to rebuild refs even if fetch failed
370377 for _ , ref := range s .snaps .References () {
371378 hash , err := s .resolve (ref )
372379 if err != nil {
373380 errs = append (errs , err )
374381 continue
375382 }
376- if _ , err := s .snaps .AddOrBuild (ctx , ref , hash , s .buildSnapshot ); err != nil {
383+
384+ snap , err := s .snaps .AddOrBuild (ctx , ref , hash , s .buildSnapshot )
385+ if err != nil {
377386 errs = append (errs , err )
387+ continue
388+ }
389+
390+ if snap != nil {
391+ flagsFetched += int64 (snap .TotalFlagsCount ())
378392 }
379393 }
380- return true , errors .Join (errs ... )
394+
395+ duration := time .Since (syncStart )
396+ observeSync (ctx , duration , flagsFetched , len (errs ) == 0 )
397+
398+ if len (errs ) > 0 {
399+ s .logger .Error ("git backend flag sync failed" , zap .Errors ("errors" , errs ))
400+ return false , errors .Join (errs ... )
401+ }
402+
403+ return true , nil
381404}
382405
383406func (s * SnapshotStore ) fetch (ctx context.Context , heads []string ) (bool , error ) {
0 commit comments