-
Notifications
You must be signed in to change notification settings - Fork 131
Description
Summary
ttlcache v3.4.0 introduces a goroutine leak when OnEviction
handlers are registered. The cache background goroutine is not properly cleaned up when the cleanup function returned by OnEviction()
is called, even though cache.Stop()
is also called.
Environment
- ttlcache version: v3.4.0
- Go version: go1.24
Expected Behavior
When an OnEviction
handler is registered and later cleaned up, no goroutines should leak. The cleanup function returned by OnEviction()
should ensure all related goroutines are properly terminated.
Actual Behavior
Goroutines leak when OnEviction
handlers are used, even when the cleanup function is called before cache.Stop()
. The leak is detected by go.uber.org/goleak
and shows goroutines stuck in the cache's Start()
method select loop.
Minimal reproduction code:
package main
import (
"context"
"testing"
"time"
"go.uber.org/goleak"
"github.com/jellydator/ttlcache/v3"
)
func TestOnEvictionLeak(t *testing.T) {
defer goleak.VerifyNone(t)
cache := ttlcache.New(ttlcache.WithTTL[string, string](10 * time.Millisecond))
cleanup := cache.OnEviction(func(ctx context.Context, reason ttlcache.EvictionReason, item *ttlcache.Item[string, string]) { })
go cache.Start()
cache.Set("test", "value", 5*time.Millisecond)
cleanup()
cache.Stop()
time.Sleep(time.Second)
}
Expected result:
Test passes with no goroutine leaks detected.
Actual result:
found unexpected goroutines:
[Goroutine X in state select, with github.com/jellydator/ttlcache/v3.(*Cache[...]).Start on top of the stack:
github.com/jellydator/ttlcache/v3.(*Cache[...]).Start(0x...)
/go/pkg/mod/github.com/jellydator/ttlcache/[email protected]/cache.go:689 +0x1fc
created by ...
]
Analysis
The issue appears to be related to the interaction between:
- The OnEviction handler system introduced in v3.4.0
- The cache background goroutine cleanup in the
Stop()
method
Working in v3.3.0
The same test pattern works fine in v3.3.0
Would appreciate investigation into the goroutine cleanup coordination between the OnEviction system and the main cache background goroutine.