diff options
author | John Cai <jcai@gitlab.com> | 2019-07-23 08:05:07 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2019-07-23 08:05:07 +0300 |
commit | c2a0337c53b8978eaf2ca19ba788fc220d78a63c (patch) | |
tree | 251f07dfee3a7691f2bafec249194bb7ff5059b5 | |
parent | 751bb0923b4dbeafd70ef85a47afd5e957268667 (diff) |
Adding go docs and tests for cachejc-use-trigger
-rw-r--r-- | internal/praefect/datastore/cache.go | 9 | ||||
-rw-r--r-- | internal/praefect/datastore/cache_test.go | 97 | ||||
-rw-r--r-- | internal/praefect/datastore/database/sql_datastore.go | 1 |
3 files changed, 104 insertions, 3 deletions
diff --git a/internal/praefect/datastore/cache.go b/internal/praefect/datastore/cache.go index e60a84d1a..c6ac53fd9 100644 --- a/internal/praefect/datastore/cache.go +++ b/internal/praefect/datastore/cache.go @@ -2,17 +2,20 @@ package datastore import "sync" +// Cache is a thread-safe cache meant to be used to cache results from a datastore. type Cache struct { sync.RWMutex - d map[string]interface{} + d map[string]interface{} } +// NewCache creates a new cache func NewCache() *Cache { return &Cache{ - d: make(map[string]interface{}), + d: make(map[string]interface{}), } } +// Bust creates a new map for cached values, effectively busting the entire cache. func (c *Cache) Bust() { c.Lock() defer c.Unlock() @@ -20,6 +23,8 @@ func (c *Cache) Bust() { c.d = make(map[string]interface{}) } +// GetFromCache either gets the results stored by key, or saves the results of a function call into its +// cache func (c *Cache) GetFromCache(key string, f func() (interface{}, error)) (interface{}, error) { c.RLock() defer c.RUnlock() diff --git a/internal/praefect/datastore/cache_test.go b/internal/praefect/datastore/cache_test.go new file mode 100644 index 000000000..97e0396f3 --- /dev/null +++ b/internal/praefect/datastore/cache_test.go @@ -0,0 +1,97 @@ +package datastore_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitaly/internal/praefect/datastore" +) + +func TestCacheNoHits(t *testing.T) { + c := datastore.NewCache() + + testCases := []interface{}{ + 1, "string", struct{}{}, []string{"one", "two", "three"}, + } + + for i, value := range testCases { + var cacheMiss bool + res, err := c.GetFromCache(fmt.Sprintf("%d", i), func() (interface{}, error) { + cacheMiss = true + return value, nil + }) + require.NoError(t, err) + require.Equal(t, value, res) + require.True(t, cacheMiss) + } +} + +func TestCacheAllHits(t *testing.T) { + c := datastore.NewCache() + + key, value := "the key", "the value" + + // seed the cache + _, err := c.GetFromCache(key, func() (interface{}, error) { + return value, nil + }) + require.NoError(t, err) + + testCases := []interface{}{ + 1, "string", struct{}{}, []string{"one", "two", "three"}, + } + + for _, v := range testCases { + var cacheMiss bool + res, err := c.GetFromCache(key, func() (interface{}, error) { + cacheMiss = true + return v, nil + }) + require.NoError(t, err) + require.Equal(t, value, res, "we should retrieve the existing value in the cache") + require.False(t, cacheMiss) + } +} + + +func TestCacheMissAfterBust(t *testing.T) { + c := datastore.NewCache() + + key, value := "the key", "the value" + + // seed the cache + _, err := c.GetFromCache(key, func() (interface{}, error) { + return value, nil + }) + require.NoError(t, err) + + testCases := []interface{}{ + 1, "string", struct{}{}, []string{"one", "two", "three"}, + } + + for _, v := range testCases { + var cacheMiss bool + res, err := c.GetFromCache(key, func() (interface{}, error) { + cacheMiss = true + return v, nil + }) + require.NoError(t, err) + require.Equal(t, value, res, "it should retrieve the existing value in the cache") + require.False(t, cacheMiss) + } + + c.Bust() + + newValue := []interface{}{"new", "value"} + var cacheMiss bool + + res, err := c.GetFromCache(key, func() (interface{}, error) { + cacheMiss = true + return newValue, nil + }) + require.NoError(t, err) + require.Equal(t, newValue, res, "it should return the new value") + require.True(t, cacheMiss) +}
\ No newline at end of file diff --git a/internal/praefect/datastore/database/sql_datastore.go b/internal/praefect/datastore/database/sql_datastore.go index 338168191..79eb520b3 100644 --- a/internal/praefect/datastore/database/sql_datastore.go +++ b/internal/praefect/datastore/database/sql_datastore.go @@ -55,7 +55,6 @@ func NewSQLDatastore(user, password, address, database, notificationChannel stri return &SQLDatastore{db: db, listener: listener}, nil } - func (sd *SQLDatastore) Listener() *pq.Listener { return sd.listener } |