Merge pull request #16 from alexejk/onremove

Support for OnDelete() callback
This commit is contained in:
Karl Seguin 2018-07-22 11:17:02 +07:00 committed by GitHub
commit a317416755
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 100 additions and 1 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
vendor/

25
Gopkg.lock generated Normal file
View 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
View file

@ -0,0 +1,8 @@
[[constraint]]
name = "github.com/karlseguin/expect"
version = "1.0.1"
[prune]
go-tests = true
unused-packages = true

View file

@ -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)
}
}

View file

@ -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 }

View file

@ -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
}

View file

@ -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)
}
}

View file

@ -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)