Merge pull request #16 from alexejk/onremove
Support for OnDelete() callback
This commit is contained in:
commit
a317416755
8 changed files with 100 additions and 1 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
vendor/
|
25
Gopkg.lock
generated
Normal file
25
Gopkg.lock
generated
Normal file
|
@ -0,0 +1,25 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/karlseguin/expect"
|
||||
packages = [
|
||||
".",
|
||||
"build",
|
||||
"mock"
|
||||
]
|
||||
revision = "4fcda73748276dc72bcc09729bdb56242093c12c"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/wsxiaoys/terminal"
|
||||
packages = ["color"]
|
||||
revision = "0940f3fc43a0ed42d04916b1c04578462c650b09"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "a7bf38c5b0c419759438d9dca1af1ee50d70f07bc087f713c2ae35cbebdaf84b"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
8
Gopkg.toml
Normal file
8
Gopkg.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
[[constraint]]
|
||||
name = "github.com/karlseguin/expect"
|
||||
version = "1.0.1"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
3
cache.go
3
cache.go
|
@ -186,6 +186,9 @@ func (c *Cache) doDelete(item *Item) {
|
|||
item.promotions = -2
|
||||
} else {
|
||||
c.size -= item.size
|
||||
if c.onDelete != nil {
|
||||
c.onDelete(item)
|
||||
}
|
||||
c.list.Remove(item.element)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,28 @@ func (_ CacheTests) DeletesAValue() {
|
|||
Expect(cache.Get("worm").Value()).To.Equal("sand")
|
||||
}
|
||||
|
||||
func (_ CacheTests) OnDeleteCallbackCalled() {
|
||||
|
||||
onDeleteFnCalled := false
|
||||
onDeleteFn := func(item *Item) {
|
||||
if item.key == "spice" {
|
||||
onDeleteFnCalled = true
|
||||
}
|
||||
}
|
||||
|
||||
cache := New(Configure().OnDelete(onDeleteFn))
|
||||
cache.Set("spice", "flow", time.Minute)
|
||||
cache.Set("worm", "sand", time.Minute)
|
||||
|
||||
time.Sleep(time.Millisecond * 10) // Run once to init
|
||||
cache.Delete("spice")
|
||||
time.Sleep(time.Millisecond * 10) // Wait for worker to pick up deleted items
|
||||
|
||||
Expect(cache.Get("spice")).To.Equal(nil)
|
||||
Expect(cache.Get("worm").Value()).To.Equal("sand")
|
||||
Expect(onDeleteFnCalled).To.Equal(true)
|
||||
}
|
||||
|
||||
func (_ CacheTests) FetchesExpiredItems() {
|
||||
cache := New(Configure())
|
||||
fn := func() (interface{}, error) { return "moo-moo", nil }
|
||||
|
|
|
@ -8,6 +8,7 @@ type Configuration struct {
|
|||
promoteBuffer int
|
||||
getsPerPromote int32
|
||||
tracking bool
|
||||
onDelete func(item *Item)
|
||||
}
|
||||
|
||||
// Creates a configuration object with sensible defaults
|
||||
|
@ -92,3 +93,11 @@ func (c *Configuration) Track() *Configuration {
|
|||
c.tracking = true
|
||||
return c
|
||||
}
|
||||
|
||||
// OnDelete allows setting a callback function to react to ideam deletion.
|
||||
// This typically allows to do a cleanup of resources, such as calling a Close() on
|
||||
// cached object that require some kind of tear-down.
|
||||
func (c *Configuration) OnDelete(callback func(item *Item)) *Configuration {
|
||||
c.onDelete = callback
|
||||
return c
|
||||
}
|
||||
|
|
|
@ -195,6 +195,9 @@ func (c *LayeredCache) worker() {
|
|||
item.promotions = -2
|
||||
} else {
|
||||
c.size -= item.size
|
||||
if c.onDelete != nil {
|
||||
c.onDelete(item)
|
||||
}
|
||||
c.list.Remove(item.element)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package ccache
|
||||
|
||||
import (
|
||||
. "github.com/karlseguin/expect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
. "github.com/karlseguin/expect"
|
||||
)
|
||||
|
||||
type LayeredCacheTests struct{}
|
||||
|
@ -65,6 +66,33 @@ func (_ *LayeredCacheTests) DeletesAValue() {
|
|||
Expect(cache.Get("leto", "sister").Value()).To.Equal("ghanima")
|
||||
}
|
||||
|
||||
func (_ *LayeredCacheTests) OnDeleteCallbackCalled() {
|
||||
|
||||
onDeleteFnCalled := false
|
||||
onDeleteFn := func(item *Item) {
|
||||
|
||||
if item.group == "spice" && item.key == "flow" {
|
||||
onDeleteFnCalled = true
|
||||
}
|
||||
}
|
||||
|
||||
cache := Layered(Configure().OnDelete(onDeleteFn))
|
||||
cache.Set("spice", "flow", "value-a", time.Minute)
|
||||
cache.Set("spice", "must", "value-b", time.Minute)
|
||||
cache.Set("leto", "sister", "ghanima", time.Minute)
|
||||
|
||||
time.Sleep(time.Millisecond * 10) // Run once to init
|
||||
cache.Delete("spice", "flow")
|
||||
time.Sleep(time.Millisecond * 10) // Wait for worker to pick up deleted items
|
||||
|
||||
Expect(cache.Get("spice", "flow")).To.Equal(nil)
|
||||
Expect(cache.Get("spice", "must").Value()).To.Equal("value-b")
|
||||
Expect(cache.Get("spice", "worm")).To.Equal(nil)
|
||||
Expect(cache.Get("leto", "sister").Value()).To.Equal("ghanima")
|
||||
|
||||
Expect(onDeleteFnCalled).To.Equal(true)
|
||||
}
|
||||
|
||||
func (_ *LayeredCacheTests) DeletesALayer() {
|
||||
cache := newLayered()
|
||||
cache.Set("spice", "flow", "value-a", time.Minute)
|
||||
|
|
Loading…
Reference in a new issue