diff --git a/go.mod b/go.mod index 97983727..93cfbf8c 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/TwiN/g8 v1.3.0 - github.com/TwiN/gocache/v2 v2.0.0 + github.com/TwiN/gocache/v2 v2.1.0 github.com/TwiN/health v1.4.0 github.com/coreos/go-oidc/v3 v3.1.0 github.com/go-ping/ping v0.0.0-20210911151512-381826476871 diff --git a/go.sum b/go.sum index a2e43f28..2c7efcc6 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/TwiN/g8 v1.3.0 h1:mNv3R35GhDn1gEV0BKMl1oupZ1tDtOWPTHUKu+W/k3U= github.com/TwiN/g8 v1.3.0/go.mod h1:SiIdItS0agSUloFqdQQt/RObB2jGSq+nnE9WfFv3RIo= -github.com/TwiN/gocache/v2 v2.0.0 h1:CPbDNKdSJpmBkh7aWcO7D3KK1yWaMlwX+3dsBPE8/so= -github.com/TwiN/gocache/v2 v2.0.0/go.mod h1:j4MABVaia2Tp53ERWc/3l4YxkswtPjB2hQzmL/kD/VQ= +github.com/TwiN/gocache/v2 v2.1.0 h1:AJnSX7Sgz22fsO7rdXYQzMQ4zWpMjBKqk70ADeqtLDU= +github.com/TwiN/gocache/v2 v2.1.0/go.mod h1:AKHAFZSwLLmoLm1a2siDOWmZ2RjIKqentRGfOFWkllY= github.com/TwiN/health v1.4.0 h1:Ts7lb4ihYDpVEbFSGAhSEZTSwuDOADnwJLFngFl4xzw= github.com/TwiN/health v1.4.0/go.mod h1:CSUh+ryfD2POS2vKtc/yO4IxgR58lKvQ0/8qnoPqPqs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= diff --git a/storage/store/memory/memory.go b/storage/store/memory/memory.go index d64ac942..a0df352d 100644 --- a/storage/store/memory/memory.go +++ b/storage/store/memory/memory.go @@ -1,7 +1,6 @@ package memory import ( - "encoding/gob" "sort" "sync" "time" @@ -13,14 +12,6 @@ import ( "github.com/TwiN/gocache/v2" ) -func init() { - gob.Register(&core.EndpointStatus{}) - gob.Register(&core.HourlyUptimeStatistics{}) - gob.Register(&core.Uptime{}) - gob.Register(&core.Result{}) - gob.Register(&core.Event{}) -} - // Store that leverages gocache type Store struct { sync.RWMutex @@ -32,7 +23,7 @@ type Store struct { // // This store holds everything in memory, and if the file parameter is not blank, // supports eventual persistence. -func NewStore(file string) (*Store, error) { +func NewStore() (*Store, error) { store := &Store{ cache: gocache.NewCache().WithMaxSize(gocache.NoMaxSize), } diff --git a/storage/store/memory/memory_test.go b/storage/store/memory/memory_test.go index 712bf426..dac2ef5a 100644 --- a/storage/store/memory/memory_test.go +++ b/storage/store/memory/memory_test.go @@ -82,7 +82,7 @@ var ( // Note that are much more extensive tests in /storage/store/store_test.go. // This test is simply an extra sanity check func TestStore_SanityCheck(t *testing.T) { - store, _ := NewStore("") + store, _ := NewStore() defer store.Close() store.Insert(&testEndpoint, &testSuccessfulResult) endpointStatuses, _ := store.GetAllEndpointStatuses(paging.NewEndpointStatusParams()) @@ -122,22 +122,14 @@ func TestStore_SanityCheck(t *testing.T) { } func TestStore_Save(t *testing.T) { - files := []string{ - "", - t.TempDir() + "/test.db", + store, err := NewStore() + if err != nil { + t.Fatal("expected no error, got", err.Error()) } - for _, file := range files { - t.Run(file, func(t *testing.T) { - store, err := NewStore(file) - if err != nil { - t.Fatal("expected no error, got", err.Error()) - } - err = store.Save() - if err != nil { - t.Fatal("expected no error, got", err.Error()) - } - store.Clear() - store.Close() - }) + err = store.Save() + if err != nil { + t.Fatal("expected no error, got", err.Error()) } + store.Clear() + store.Close() } diff --git a/storage/store/store.go b/storage/store/store.go index 11de69ef..53ecb1b3 100644 --- a/storage/store/store.go +++ b/storage/store/store.go @@ -110,15 +110,7 @@ func Initialize(cfg *storage.Config) error { case storage.TypeMemory: fallthrough default: - if len(cfg.Path) > 0 { - store, err = memory.NewStore(cfg.Path) - if err != nil { - return err - } - go autoSave(ctx, store, 7*time.Minute) - } else { - store, _ = memory.NewStore("") - } + store, _ = memory.NewStore() } return nil } diff --git a/storage/store/store_bench_test.go b/storage/store/store_bench_test.go index 940fdfb3..800b380c 100644 --- a/storage/store/store_bench_test.go +++ b/storage/store/store_bench_test.go @@ -12,7 +12,7 @@ import ( ) func BenchmarkStore_GetAllEndpointStatuses(b *testing.B) { - memoryStore, err := memory.NewStore("") + memoryStore, err := memory.NewStore() if err != nil { b.Fatal("failed to create store:", err.Error()) } @@ -81,7 +81,7 @@ func BenchmarkStore_GetAllEndpointStatuses(b *testing.B) { } func BenchmarkStore_Insert(b *testing.B) { - memoryStore, err := memory.NewStore("") + memoryStore, err := memory.NewStore() if err != nil { b.Fatal("failed to create store:", err.Error()) } @@ -153,7 +153,7 @@ func BenchmarkStore_Insert(b *testing.B) { } func BenchmarkStore_GetEndpointStatusByKey(b *testing.B) { - memoryStore, err := memory.NewStore("") + memoryStore, err := memory.NewStore() if err != nil { b.Fatal("failed to create store:", err.Error()) } diff --git a/storage/store/store_test.go b/storage/store/store_test.go index 8e6e547d..f06f2a69 100644 --- a/storage/store/store_test.go +++ b/storage/store/store_test.go @@ -89,7 +89,7 @@ type Scenario struct { } func initStoresAndBaseScenarios(t *testing.T, testName string) []*Scenario { - memoryStore, err := memory.NewStore("") + memoryStore, err := memory.NewStore() if err != nil { t.Fatal("failed to create store:", err.Error()) } @@ -528,17 +528,17 @@ func TestStore_DeleteAllEndpointStatusesNotInKeys(t *testing.T) { scenario.Store.Insert(&firstEndpoint, result) scenario.Store.Insert(&secondEndpoint, result) if ss, _ := scenario.Store.GetEndpointStatusByKey(firstEndpoint.Key(), paging.NewEndpointStatusParams()); ss == nil { - t.Fatal("firstEndpoint should exist") + t.Fatal("firstEndpoint should exist, got", ss) } if ss, _ := scenario.Store.GetEndpointStatusByKey(secondEndpoint.Key(), paging.NewEndpointStatusParams()); ss == nil { - t.Fatal("secondEndpoint should exist") + t.Fatal("secondEndpoint should exist, got", ss) } scenario.Store.DeleteAllEndpointStatusesNotInKeys([]string{firstEndpoint.Key()}) if ss, _ := scenario.Store.GetEndpointStatusByKey(firstEndpoint.Key(), paging.NewEndpointStatusParams()); ss == nil { - t.Error("secondEndpoint should've been deleted") + t.Error("secondEndpoint should still exist, got", ss) } if ss, _ := scenario.Store.GetEndpointStatusByKey(secondEndpoint.Key(), paging.NewEndpointStatusParams()); ss != nil { - t.Error("firstEndpoint should still exist") + t.Error("firstEndpoint should have been deleted, got", ss) } // Delete everything scenario.Store.DeleteAllEndpointStatusesNotInKeys([]string{}) diff --git a/vendor/github.com/TwiN/gocache/v2/LICENSE.md b/vendor/github.com/TwiN/gocache/v2/LICENSE.md index ca64af38..3453cb7b 100644 --- a/vendor/github.com/TwiN/gocache/v2/LICENSE.md +++ b/vendor/github.com/TwiN/gocache/v2/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 TwiN +Copyright (c) 2022 TwiN Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/vendor/github.com/TwiN/gocache/v2/README.md b/vendor/github.com/TwiN/gocache/v2/README.md index 1513206d..fd623662 100644 --- a/vendor/github.com/TwiN/gocache/v2/README.md +++ b/vendor/github.com/TwiN/gocache/v2/README.md @@ -1,9 +1,9 @@ # gocache -![build](https://github.com/TwiN/gocache/workflows/build/badge.svg?branch=master) +![test](https://github.com/TwiN/gocache/workflows/test/badge.svg?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/TwiN/gocache)](https://goreportcard.com/report/github.com/TwiN/gocache) [![codecov](https://codecov.io/gh/TwiN/gocache/branch/master/graph/badge.svg)](https://codecov.io/gh/TwiN/gocache) [![Go version](https://img.shields.io/github/go-mod/go-version/TwiN/gocache.svg)](https://github.com/TwiN/gocache) -[![Go Reference](https://pkg.go.dev/badge/github.com/TwiN/gocache.svg)](https://pkg.go.dev/github.com/TwiN/gocache) +[![Go Reference](https://pkg.go.dev/badge/github.com/TwiN/gocache.svg)](https://pkg.go.dev/github.com/TwiN/gocache/v2) [![Follow TwiN](https://img.shields.io/github/followers/TwiN?label=Follow&style=social)](https://github.com/TwiN) gocache is an easy-to-use, high-performance, lightweight and thread-safe (goroutine-safe) in-memory key-value cache @@ -65,27 +65,28 @@ cache.StartJanitor() ``` ### Functions -| Function | Description | -| --------------------------------- | ----------- | -| WithMaxSize | Sets the max size of the cache. `gocache.NoMaxSize` means there is no limit. If not set, the default max size is `gocache.DefaultMaxSize`. -| WithMaxMemoryUsage | Sets the max memory usage of the cache. `gocache.NoMaxMemoryUsage` means there is no limit. The default behavior is to not evict based on memory usage. -| WithEvictionPolicy | Sets the eviction algorithm to be used when the cache reaches the max size. If not set, the default eviction policy is `gocache.FirstInFirstOut` (FIFO). -| WithForceNilInterfaceOnNilPointer | Configures whether values with a nil pointer passed to write functions should be forcefully set to nil. Defaults to true. -| StartJanitor | Starts the janitor, which is in charge of deleting expired cache entries in the background. -| StopJanitor | Stops the janitor. -| Set | Same as `SetWithTTL`, but with no expiration (`gocache.NoExpiration`) -| SetAll | Same as `Set`, but in bulk -| SetWithTTL | Creates or updates a cache entry with the given key, value and expiration time. If the max size after the aforementioned operation is above the configured max size, the tail will be evicted. Depending on the eviction policy, the tail is defined as the oldest -| Get | Gets a cache entry by its key. -| GetByKeys | Gets a map of entries by their keys. The resulting map will contain all keys, even if some of the keys in the slice passed as parameter were not present in the cache. -| GetAll | Gets all cache entries. -| GetKeysByPattern | Retrieves a slice of keys that matches a given pattern. -| Delete | Removes a key from the cache. -| DeleteAll | Removes multiple keys from the cache. -| Count | Gets the size of the cache. This includes cache keys which may have already expired, but have not been removed yet. -| Clear | Wipes the cache. -| TTL | Gets the time until a cache key expires. -| Expire | Sets the expiration time of an existing cache key. +| Function | Description | +|-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| WithMaxSize | Sets the max size of the cache. `gocache.NoMaxSize` means there is no limit. If not set, the default max size is `gocache.DefaultMaxSize`. | +| WithMaxMemoryUsage | Sets the max memory usage of the cache. `gocache.NoMaxMemoryUsage` means there is no limit. The default behavior is to not evict based on memory usage. | +| WithEvictionPolicy | Sets the eviction algorithm to be used when the cache reaches the max size. If not set, the default eviction policy is `gocache.FirstInFirstOut` (FIFO). | +| WithForceNilInterfaceOnNilPointer | Configures whether values with a nil pointer passed to write functions should be forcefully set to nil. Defaults to true. | +| StartJanitor | Starts the janitor, which is in charge of deleting expired cache entries in the background. | +| StopJanitor | Stops the janitor. | +| Set | Same as `SetWithTTL`, but with no expiration (`gocache.NoExpiration`) | +| SetAll | Same as `Set`, but in bulk | +| SetWithTTL | Creates or updates a cache entry with the given key, value and expiration time. If the max size after the aforementioned operation is above the configured max size, the tail will be evicted. Depending on the eviction policy, the tail is defined as the oldest | +| Get | Gets a cache entry by its key. | +| GetByKeys | Gets a map of entries by their keys. The resulting map will contain all keys, even if some of the keys in the slice passed as parameter were not present in the cache. | +| GetAll | Gets all cache entries. | +| GetKeysByPattern | Retrieves a slice of keys that matches a given pattern. | +| Delete | Removes a key from the cache. | +| DeleteAll | Removes multiple keys from the cache. | +| DeleteKeysByPattern | Removes all keys that that matches a given pattern. | +| Count | Gets the size of the cache. This includes cache keys which may have already expired, but have not been removed yet. | +| Clear | Wipes the cache. | +| TTL | Gets the time until a cache key expires. | +| Expire | Sets the expiration time of an existing cache key. | For further documentation, please refer to [Go Reference](https://pkg.go.dev/github.com/TwiN/gocache) @@ -132,7 +133,7 @@ func main() { cache.SetWithTTL("key-with-ttl", "value", 60*time.Minute) cache.SetAll(map[string]interface{}{"k1": "v1", "k2": "v2", "k3": "v3"}) - fmt.Println("[Count] Cache size:", cache.Count()) + fmt.Println("[Count] Cache size:", cache.Count()) value, exists := cache.Get("key") fmt.Printf("[Get] key=key; value=%s; exists=%v\n", value, exists) @@ -345,8 +346,8 @@ import ( var cache = gocache.NewCache() func main() { - data := retrieveCacheEntriesUsingWhateverMeanYouUsedToPersistIt() - cache.SetAll(data) + data := retrieveCacheEntriesUsingWhateverMeanYouUsedToPersistIt() + cache.SetAll(data) // Start everything else on another goroutine to prevent blocking the main goroutine go Start() // Wait for termination signal diff --git a/vendor/github.com/TwiN/gocache/v2/gocache.go b/vendor/github.com/TwiN/gocache/v2/gocache.go index 4456e9a0..ab462db3 100644 --- a/vendor/github.com/TwiN/gocache/v2/gocache.go +++ b/vendor/github.com/TwiN/gocache/v2/gocache.go @@ -311,8 +311,8 @@ func (cache *Cache) Get(key string) (interface{}, bool) { cache.mutex.Lock() entry, ok := cache.get(key) if !ok { - cache.mutex.Unlock() cache.stats.Misses++ + cache.mutex.Unlock() return nil, false } if entry.Expired() { @@ -388,8 +388,7 @@ func (cache *Cache) GetAll() map[string]interface{} { // cache.GetKeysByPattern("*some*", 0) will return all keys containing "some" in them // cache.GetKeysByPattern("*some*", 5) will return 5 keys (or less) containing "some" in them // -// Note that GetKeysByPattern does not trigger active evictions, nor does it count as accessing the entry, the latter -// only applying if the cache uses the LeastRecentlyUsed eviction policy. +// Note that GetKeysByPattern does not trigger active evictions, nor does it count as accessing the entry (if LRU). // The reason for that behavior is that these two (active eviction and access) only applies when you access the value // of the cache entry, and this function only returns the keys. func (cache *Cache) GetKeysByPattern(pattern string, limit int) []string { @@ -435,6 +434,13 @@ func (cache *Cache) DeleteAll(keys []string) int { return numberOfKeysDeleted } +// DeleteKeysByPattern deletes all entries matching a given key pattern and returns the number of entries deleted. +// +// Note that DeleteKeysByPattern does not trigger active evictions, nor does it count as accessing the entry (if LRU). +func (cache *Cache) DeleteKeysByPattern(pattern string) int { + return cache.DeleteAll(cache.GetKeysByPattern(pattern, 0)) +} + // Count returns the total amount of entries in the cache, regardless of whether they're expired or not func (cache *Cache) Count() int { cache.mutex.RLock() diff --git a/vendor/modules.txt b/vendor/modules.txt index e512403d..78744aea 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,8 +1,8 @@ # github.com/TwiN/g8 v1.3.0 ## explicit; go 1.17 github.com/TwiN/g8 -# github.com/TwiN/gocache/v2 v2.0.0 -## explicit; go 1.17 +# github.com/TwiN/gocache/v2 v2.1.0 +## explicit; go 1.18 github.com/TwiN/gocache/v2 # github.com/TwiN/health v1.4.0 ## explicit; go 1.18