Skip to content

Commit a406ca2

Browse files
author
ThanhNguyxn
committed
fix(store): add proper GC with Handler and interval gating
Address maintainer feedback on PR #1239: - Add Handler: repo.DeleteObject to prevent nil panic in Prune - Handle ErrLooseObjectsNotSupported gracefully - Add 5-minute interval gating to avoid repack overhead on every write - Remove sirupsen/logrus dependency (best-effort silent GC) Fixes #1104
1 parent c82d8e2 commit a406ca2

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

internal/store/gitstore.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import (
2121
cliproxyauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
2222
)
2323

24+
// gcInterval defines minimum time between garbage collection runs.
25+
const gcInterval = 5 * time.Minute
26+
2427
// GitTokenStore persists token records and auth metadata using git as the backing storage.
2528
type GitTokenStore struct {
2629
mu sync.Mutex
@@ -31,6 +34,7 @@ type GitTokenStore struct {
3134
remote string
3235
username string
3336
password string
37+
lastGC time.Time
3438
}
3539

3640
// NewGitTokenStore creates a token store that saves credentials to disk through the
@@ -613,6 +617,7 @@ func (s *GitTokenStore) commitAndPushLocked(message string, relPaths ...string)
613617
} else if errRewrite := s.rewriteHeadAsSingleCommit(repo, headRef.Name(), commitHash, message, signature); errRewrite != nil {
614618
return errRewrite
615619
}
620+
s.maybeRunGC(repo)
616621
if err = repo.Push(&git.PushOptions{Auth: s.gitAuth(), Force: true}); err != nil {
617622
if errors.Is(err, git.NoErrAlreadyUpToDate) {
618623
return nil
@@ -652,6 +657,23 @@ func (s *GitTokenStore) rewriteHeadAsSingleCommit(repo *git.Repository, branch p
652657
return nil
653658
}
654659

660+
func (s *GitTokenStore) maybeRunGC(repo *git.Repository) {
661+
now := time.Now()
662+
if now.Sub(s.lastGC) < gcInterval {
663+
return
664+
}
665+
s.lastGC = now
666+
667+
pruneOpts := git.PruneOptions{
668+
OnlyObjectsOlderThan: now,
669+
Handler: repo.DeleteObject,
670+
}
671+
if err := repo.Prune(pruneOpts); err != nil && !errors.Is(err, git.ErrLooseObjectsNotSupported) {
672+
return
673+
}
674+
_ = repo.RepackObjects(&git.RepackConfig{})
675+
}
676+
655677
// PersistConfig commits and pushes configuration changes to git.
656678
func (s *GitTokenStore) PersistConfig(_ context.Context) error {
657679
if err := s.EnsureRepository(); err != nil {

0 commit comments

Comments
 (0)