summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/service/gc.go21
-rw-r--r--internal/service/gc_test.go11
2 files changed, 29 insertions, 3 deletions
diff --git a/internal/service/gc.go b/internal/service/gc.go
index f95b12a..ef206fa 100644
--- a/internal/service/gc.go
+++ b/internal/service/gc.go
@@ -21,6 +21,8 @@ type GCWorker struct {
age time.Duration
logger *slog.Logger
ticker *time.Ticker
+ tickCh <-chan time.Time
+ runDoneCh chan struct{}
stopCh chan struct{}
stopOnce sync.Once
wg sync.WaitGroup
@@ -57,14 +59,19 @@ func (w *GCWorker) WithInterval(interval time.Duration) *GCWorker {
// Start launches the GC goroutine.
func (w *GCWorker) Start() {
w.ctx, w.cancel = context.WithCancel(context.Background())
- w.ticker = time.NewTicker(w.interval)
+ tickCh := w.tickCh
+ if tickCh == nil {
+ w.ticker = time.NewTicker(w.interval)
+ tickCh = w.ticker.C
+ }
w.wg.Add(1)
go func() {
defer w.wg.Done()
for {
select {
- case <-w.ticker.C:
+ case <-tickCh:
w.run(w.ctx)
+ w.notifyRunDone()
case <-w.stopCh:
return
}
@@ -129,6 +136,16 @@ func (w *GCWorker) run(ctx context.Context) {
}
}
+func (w *GCWorker) notifyRunDone() {
+ if w.runDoneCh == nil {
+ return
+ }
+ select {
+ case w.runDoneCh <- struct{}{}:
+ default:
+ }
+}
+
// RunOnce performs a single GC run synchronously. Useful for tests.
func (w *GCWorker) RunOnce() error {
if w.interval == 0 {
diff --git a/internal/service/gc_test.go b/internal/service/gc_test.go
index c2bf708..26a2160 100644
--- a/internal/service/gc_test.go
+++ b/internal/service/gc_test.go
@@ -89,8 +89,17 @@ func TestGCWorker_StartStop(t *testing.T) {
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError}))
w := NewGCWorker(store, &clock.MockClock{T: now}, tmpDir, 10*time.Millisecond, logger).WithAge(7 * 24 * time.Hour)
+ tickCh := make(chan time.Time, 1)
+ runDoneCh := make(chan struct{}, 1)
+ w.tickCh = tickCh
+ w.runDoneCh = runDoneCh
w.Start()
- time.Sleep(50 * time.Millisecond)
+ tickCh <- now
+ select {
+ case <-runDoneCh:
+ case <-time.After(time.Second):
+ t.Fatal("timed out waiting for gc run")
+ }
w.Stop()
if !called {