Partially fixing #3.
On close, drain the deletables channel (unblocking an waiting goroutines) and close deletables. Like Gets and Sets against a now-closed promotables, this means any subsequent to Deletes from deletables will panic. I'm still not sure that this is ccache's responsibility. If a client closes a DB connection, we'd expect subsequent operations against the now-closed connection to fail. My main problems with defer'ing a recover are: 1 - the performance overhead on every single get / set / delete 2 - not communicating with the caller that the requested operatin is no longer valid.
This commit is contained in:
21
cache.go
21
cache.go
@@ -150,20 +150,35 @@ func (c *Cache) worker() {
|
||||
select {
|
||||
case item, ok := <-c.promotables:
|
||||
if ok == false {
|
||||
return
|
||||
goto drain
|
||||
}
|
||||
if c.doPromote(item) && c.size > c.maxSize {
|
||||
c.gc()
|
||||
}
|
||||
case item := <-c.deletables:
|
||||
c.doDelete(item)
|
||||
}
|
||||
}
|
||||
|
||||
drain:
|
||||
for {
|
||||
select {
|
||||
case item := <-c.deletables:
|
||||
c.doDelete(item)
|
||||
default:
|
||||
close(c.deletables)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) doDelete(item *Item) {
|
||||
if item.element == nil {
|
||||
item.promotions = -2
|
||||
} else {
|
||||
c.size -= item.size
|
||||
c.list.Remove(item.element)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) doPromote(item *Item) bool {
|
||||
|
Reference in New Issue
Block a user