ttlcache
ttlcache copied to clipboard
PurgeCallback to be called on Purge()
I needed a callback to be called on Purge. If I just wrapped it in an internal package, I'd invent a possible race condition:
thread1 purges
thread2 adds
add callback
purge callback
Thus this PR.
Sorry for the delay. It was a bit busy here.
I notice in your PR that you try to avoid a race condition, but in any case you are also introducing one by not having a lock around the SetPurgeCallback
call. If you can add that then i think we can add it.
It is worth noting that v3 has a similar (if not the same) feature: it calls all registered callbacks when DeleteAll()
(the successor of Purge()
) is called.
So you can update this for v2, or wait a few weeks for v3 (with generics support)
Now it's me, who was busy.
Yes, lack of mutex in SetPurgeCallback
is definitely a miss (and inconsistency). I'll try to update it to v2 soon.
My point was to invent a dedicated callback for Purge() to let user know that absolutely everything is deleted. As far as I understand, v3 calls Evict callback for every deleted item: that leads to multiple calls instead of one. In my case I wanted to cleanup some linked data and clean it once.
In v3, cache.Len()
can be combined with cache.OnEviction()
to achieve what you need:
var (
mu sync.Mutex
needsCleanup bool
)
cache.OnEviction(func(ctx context.Context, r EvictionReason, item *Item[K, V]) {
if r != EvictionReasonDeleted || cache.Len() > 0 {
return
}
mu.Lock()
defer mu.Unlock()
if needsCleanup {
needsCleanup = false
go func() {
// clean up
}()
}
})
cache.OnInsertion(func(ctx context.Context, item *Item[K, V]) {
if cache.Len() == 0 {
return
}
mu.Lock()
defer mu.Unlock()
if !needsCleanup {
needsCleanup = true
go func() {
// set up
}()
}
})
I'm closing this PR since the same result can already be achieved in the latest version.