Comments (5)
thanks for the detailed report, it really helped narrow it down. I added a slightly modified version of your test :)
from ccache.
I think there is still a problem here. If a node is in both the deletables
and the promotables
, and deletables
is consumed before promotables
, the node will be Remove()
twice, causing gc()
to fail.
deletables
->doDelete()
->Remove()
promotables
->doPromote()
->MoveToFront()
->Remove()
gc()
node == nil, then fail
If you keep this test case running, it will fail
func Test_CachePrune(t *testing.T) {
maxSize := int64(500)
cache := New(Configure[string]().MaxSize(maxSize).ItemsToPrune(50))
epoch := 0
for {
epoch += 1
expired := make([]string, 0)
for i := 0; i < 50; i += 1 {
key := strconv.FormatInt(rand.Int63n(maxSize*20), 10)
item := cache.Get(key)
if item == nil || item.TTL() > 1*time.Minute {
expired = append(expired, key)
}
}
for _, key := range expired {
cache.Set(key, key, 5*time.Minute)
}
if epoch%500 == 0 {
fmt.Printf("size=%d, dropped=%d\n", cache.GetSize(), cache.GetDropped())
}
if cache.GetSize() > 5000 {
fmt.Printf("size=%d, dropped=%d\n", cache.GetSize(), cache.GetDropped())
t.Fail()
return
}
}
}
I think the fix is let list.node = nil (and maybe item.promotions = -2) after Remove()
in doDelete()
, same as in gc()
.
func (c *Cache[T]) doDelete(item *Item[T]) {
if item.node == nil {
item.promotions = -2
} else {
c.size -= item.size
if c.onDelete != nil {
c.onDelete(item)
}
c.list.Remove(item.node)
item.node = nil // fix
item.promotions = -2 // fix
}
}
from ccache.
FYI, not sure I'll be able to look into this until early next week, sorry.
from ccache.
I think this commit solves the issue, could you release a new tag? thanks.
from ccache.
sure, done
from ccache.
Related Issues (20)
- Fetch() is not atomic HOT 2
- ability to set an item that never expires HOT 2
- would like a version of Fetch that doesn't require a closure HOT 4
- Stop can cause race detector errors in testing HOT 14
- Bug report: item leak when c.promotables is busy HOT 1
- Bug report: TrackingGet goroutine unsafe with onDelete func HOT 1
- How to get the max performance? HOT 3
- Not Promote on Get HOT 2
- How to promote directly saved item? HOT 1
- OnDelete not called in LayeredCache.gc
- High lock contention in LayeredCache.set with few primary keys HOT 1
- memory leak HOT 3
- New release implemented via generics? HOT 1
- Bug Report: v3.0.1 gc may failed
- When max size is 3, set() not delete superfluous data HOT 4
- Memory leak during cleanup
- Generic key type HOT 2
- ttl not working HOT 4
- Fix flaky test HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ccache.