Skip to content

Commit

Permalink
make Close operation idempotent
Browse files Browse the repository at this point in the history
Previously, second call of LoadingCache.Close() resulted in panic.
  • Loading branch information
paskal committed Dec 26, 2022
1 parent 6ad2143 commit 1abcd28
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
6 changes: 6 additions & 0 deletions internal/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ func (c *LoadingCache) ItemCount() int {
func (c *LoadingCache) Close() {
c.mu.Lock()
defer c.mu.Unlock()
// don't panic in case service is already closed
select {
case <-c.done:
return
default:
}
close(c.done)
}

Expand Down
11 changes: 11 additions & 0 deletions internal/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
func TestLoadingCacheNoPurge(t *testing.T) {
lc, err := NewLoadingCache()
assert.NoError(t, err)
defer lc.Close()

lc.Set("key1", "val1")
assert.Equal(t, 1, lc.ItemCount())
Expand Down Expand Up @@ -112,6 +113,7 @@ func TestLoadingCacheWithPurgeMax(t *testing.T) {
func TestLoadingCacheConcurrency(t *testing.T) {
lc, err := NewLoadingCache()
assert.NoError(t, err)
defer lc.Close()
wg := sync.WaitGroup{}
wg.Add(1000)
for i := 0; i < 1000; i++ {
Expand All @@ -128,6 +130,7 @@ func TestLoadingCacheInvalidateAndEvict(t *testing.T) {
var evicted int
lc, err := NewLoadingCache(OnEvicted(func(_ string, _ interface{}) { evicted++ }))
assert.NoError(t, err)
defer lc.Close()

lc.Set("key1", "val1")
lc.Set("key2", "val2")
Expand Down Expand Up @@ -167,6 +170,7 @@ func TestLoadingCacheBadOption(t *testing.T) {
func TestLoadingExpired(t *testing.T) {
lc, err := NewLoadingCache(TTL(time.Millisecond * 5))
assert.NoError(t, err)
defer lc.Close()

lc.Set("key1", "val1")
assert.Equal(t, 1, lc.ItemCount())
Expand All @@ -190,3 +194,10 @@ func TestLoadingExpired(t *testing.T) {
assert.Empty(t, v)
assert.False(t, ok)
}

func TestDoubleClose(t *testing.T) {
lc, err := NewLoadingCache(TTL(time.Millisecond * 5))
assert.NoError(t, err)
lc.Close()
lc.Close() // don't panic in case service is already closed
}

0 comments on commit 1abcd28

Please sign in to comment.