-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update README with new bagdes (License and Report) * Change the documention
- Loading branch information
Showing
17 changed files
with
744 additions
and
738 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,29 @@ | ||
package cachego | ||
|
||
import ( | ||
"time" | ||
"time" | ||
) | ||
|
||
type ( | ||
// Cache is the top-level cache interface | ||
Cache interface { | ||
// Cache is the top-level cache interface | ||
Cache interface { | ||
|
||
// Contains check if a cached key exists | ||
Contains(key string) bool | ||
// Contains check if a cached key exists | ||
Contains(key string) bool | ||
|
||
// Delete remove the cached key | ||
Delete(key string) error | ||
// Delete remove the cached key | ||
Delete(key string) error | ||
|
||
// Fetch retrieve the cached key value | ||
Fetch(key string) (string, error) | ||
// Fetch retrieve the cached key value | ||
Fetch(key string) (string, error) | ||
|
||
// FetchMulti retrieve multiple cached keys value | ||
FetchMulti(keys []string) map[string]string | ||
// FetchMulti retrieve multiple cached keys value | ||
FetchMulti(keys []string) map[string]string | ||
|
||
// Flush remove all cached keys | ||
Flush() error | ||
// Flush remove all cached keys | ||
Flush() error | ||
|
||
// Save cache a value by key | ||
Save(key string, value string, lifeTime time.Duration) error | ||
} | ||
// Save cache a value by key | ||
Save(key string, value string, lifeTime time.Duration) error | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,95 @@ | ||
package cachego | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"time" | ||
"fmt" | ||
"strings" | ||
"time" | ||
) | ||
|
||
type ( | ||
// Chain storage for dealing with multiple cache storage in the same time | ||
Chain struct { | ||
drivers []Cache | ||
} | ||
// Chain storage for dealing with multiple cache storage in the same time | ||
Chain struct { | ||
drivers []Cache | ||
} | ||
) | ||
|
||
// NewChain - Create an instance of Chain | ||
// NewChain creates an instance of Chain cache driver | ||
func NewChain(drivers ...Cache) *Chain { | ||
return &Chain{drivers} | ||
return &Chain{drivers} | ||
} | ||
|
||
// Check if cached key exists in one of cache storage | ||
// Contains checks if the cached key exists in one of the cache storages | ||
func (c *Chain) Contains(key string) bool { | ||
for _, driver := range c.drivers { | ||
if driver.Contains(key) { | ||
return true | ||
} | ||
} | ||
for _, driver := range c.drivers { | ||
if driver.Contains(key) { | ||
return true | ||
} | ||
} | ||
|
||
return false | ||
return false | ||
} | ||
|
||
// Delete the cached key in all cache storages | ||
func (c *Chain) Delete(key string) error { | ||
for _, driver := range c.drivers { | ||
if err := driver.Delete(key); err != nil { | ||
return err | ||
} | ||
} | ||
for _, driver := range c.drivers { | ||
if err := driver.Delete(key); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
return nil | ||
} | ||
|
||
// Retrieves the value of the first cache storage found | ||
// Fetch retrieves the value of one of the registred cache storages | ||
func (c *Chain) Fetch(key string) (string, error) { | ||
|
||
errs := []string{} | ||
errs := []string{} | ||
|
||
for _, driver := range c.drivers { | ||
if value, err := driver.Fetch(key); err == nil { | ||
return value, nil | ||
} else { | ||
errs = append(errs, err.Error()) | ||
} | ||
} | ||
for _, driver := range c.drivers { | ||
value, err := driver.Fetch(key) | ||
|
||
return "", fmt.Errorf("Key not found in cache chain. Errors: %s", strings.Join(errs, ",")) | ||
if driver.Fetch(key); err == nil { | ||
return value, nil | ||
} | ||
|
||
errs = append(errs, err.Error()) | ||
} | ||
|
||
return "", fmt.Errorf("Key not found in cache chain. Errors: %s", strings.Join(errs, ",")) | ||
} | ||
|
||
// Retrieve multiple cached value from keys of the first cache storage found | ||
// FetchMulti retrieves multiple cached values from one of the registred cache storages | ||
func (c *Chain) FetchMulti(keys []string) map[string]string { | ||
result := make(map[string]string) | ||
result := make(map[string]string) | ||
|
||
for _, key := range keys { | ||
if value, err := c.Fetch(key); err == nil { | ||
result[key] = value | ||
} | ||
} | ||
for _, key := range keys { | ||
if value, err := c.Fetch(key); err == nil { | ||
result[key] = value | ||
} | ||
} | ||
|
||
return result | ||
return result | ||
} | ||
|
||
// Remove all cached keys of the all cache storages | ||
// Flush removes all cached keys of the registered cache storages | ||
func (c *Chain) Flush() error { | ||
for _, driver := range c.drivers { | ||
if err := driver.Flush(); err != nil { | ||
return err | ||
} | ||
} | ||
for _, driver := range c.drivers { | ||
if err := driver.Flush(); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
return nil | ||
} | ||
|
||
// Save a value in all cache storages by key | ||
func (c *Chain) Save(key string, value string, lifeTime time.Duration) error { | ||
|
||
for _, driver := range c.drivers { | ||
if err := driver.Save(key, value, lifeTime); err != nil { | ||
return err | ||
} | ||
} | ||
for _, driver := range c.drivers { | ||
if err := driver.Save(key, value, lifeTime); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,121 @@ | ||
package cachego | ||
|
||
import ( | ||
"github.com/bradfitz/gomemcache/memcache" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/suite" | ||
"testing" | ||
"time" | ||
"github.com/bradfitz/gomemcache/memcache" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/suite" | ||
"testing" | ||
"time" | ||
) | ||
|
||
type ChainTestSuite struct { | ||
suite.Suite | ||
suite.Suite | ||
|
||
assert *assert.Assertions | ||
cache Cache | ||
assert *assert.Assertions | ||
cache Cache | ||
} | ||
|
||
func (s *ChainTestSuite) SetupTest() { | ||
s.cache = NewChain(NewMap()) | ||
s.cache = NewChain(NewMap()) | ||
|
||
s.assert = assert.New(s.T()) | ||
s.assert = assert.New(s.T()) | ||
} | ||
|
||
func (s *ChainTestSuite) TestSaveThrowErrorWhenOneOfDriverFail() { | ||
cache := NewChain( | ||
NewMap(), | ||
NewMemcached(memcache.New("127.0.0.1:22222")), | ||
) | ||
cache := NewChain( | ||
NewMap(), | ||
NewMemcached(memcache.New("127.0.0.1:22222")), | ||
) | ||
|
||
s.assert.Error(cache.Save("foo", "bar", 0)) | ||
s.assert.Error(cache.Save("foo", "bar", 0)) | ||
} | ||
|
||
func (s *ChainTestSuite) TestSave() { | ||
s.assert.Nil(s.cache.Save("foo", "bar", 0)) | ||
s.assert.Nil(s.cache.Save("foo", "bar", 0)) | ||
} | ||
|
||
func (s *ChainTestSuite) TestFetchThrowErrorWhenExpired() { | ||
key := "foo" | ||
value := "bar" | ||
key := "foo" | ||
value := "bar" | ||
|
||
s.cache.Save(key, value, 1*time.Second) | ||
s.cache.Save(key, value, 1*time.Second) | ||
|
||
time.Sleep(1 * time.Second) | ||
time.Sleep(1 * time.Second) | ||
|
||
result, err := s.cache.Fetch(key) | ||
result, err := s.cache.Fetch(key) | ||
|
||
s.assert.Regexp("^Key not found in cache chain", err) | ||
s.assert.Empty(result) | ||
s.assert.Regexp("^Key not found in cache chain", err) | ||
s.assert.Empty(result) | ||
} | ||
|
||
func (s *ChainTestSuite) TestFetch() { | ||
key := "foo" | ||
value := "bar" | ||
key := "foo" | ||
value := "bar" | ||
|
||
s.cache.Save(key, value, 0) | ||
s.cache.Save(key, value, 0) | ||
|
||
result, err := s.cache.Fetch(key) | ||
result, err := s.cache.Fetch(key) | ||
|
||
s.assert.Nil(err) | ||
s.assert.Equal(value, result) | ||
s.assert.Nil(err) | ||
s.assert.Equal(value, result) | ||
} | ||
|
||
func (s *ChainTestSuite) TestContains() { | ||
s.cache.Save("foo", "bar", 0) | ||
s.cache.Save("foo", "bar", 0) | ||
|
||
s.assert.True(s.cache.Contains("foo")) | ||
s.assert.False(s.cache.Contains("bar")) | ||
s.assert.True(s.cache.Contains("foo")) | ||
s.assert.False(s.cache.Contains("bar")) | ||
} | ||
|
||
func (s *ChainTestSuite) TestDeleteThrowErrorWhenOneOfDriverFail() { | ||
cache := NewChain( | ||
NewMap(), | ||
NewMemcached(memcache.New("127.0.0.1:22222")), | ||
) | ||
cache := NewChain( | ||
NewMap(), | ||
NewMemcached(memcache.New("127.0.0.1:22222")), | ||
) | ||
|
||
s.assert.Error(cache.Delete("foo")) | ||
s.assert.Error(cache.Delete("foo")) | ||
} | ||
|
||
func (s *ChainTestSuite) TestDelete() { | ||
s.cache.Save("foo", "bar", 0) | ||
s.cache.Save("foo", "bar", 0) | ||
|
||
s.assert.Nil(s.cache.Delete("foo")) | ||
s.assert.False(s.cache.Contains("foo")) | ||
s.assert.Nil(s.cache.Delete("foo")) | ||
s.assert.False(s.cache.Contains("foo")) | ||
} | ||
|
||
func (s *ChainTestSuite) TestFlushThrowErrorWhenOneOfDriverFail() { | ||
cache := NewChain( | ||
NewMap(), | ||
NewMemcached(memcache.New("127.0.0.1:22222")), | ||
) | ||
cache := NewChain( | ||
NewMap(), | ||
NewMemcached(memcache.New("127.0.0.1:22222")), | ||
) | ||
|
||
s.assert.Error(cache.Flush()) | ||
s.assert.Error(cache.Flush()) | ||
} | ||
|
||
func (s *ChainTestSuite) TestFlush() { | ||
s.cache.Save("foo", "bar", 0) | ||
s.cache.Save("foo", "bar", 0) | ||
|
||
s.assert.Nil(s.cache.Flush()) | ||
s.assert.False(s.cache.Contains("foo")) | ||
s.assert.Nil(s.cache.Flush()) | ||
s.assert.False(s.cache.Contains("foo")) | ||
} | ||
|
||
func (s *ChainTestSuite) TestFetchMulti() { | ||
s.cache.Save("foo", "bar", 0) | ||
s.cache.Save("john", "doe", 0) | ||
s.cache.Save("foo", "bar", 0) | ||
s.cache.Save("john", "doe", 0) | ||
|
||
result := s.cache.FetchMulti([]string{"foo", "john"}) | ||
result := s.cache.FetchMulti([]string{"foo", "john"}) | ||
|
||
s.assert.Len(result, 2) | ||
s.assert.Len(result, 2) | ||
} | ||
|
||
func (s *ChainTestSuite) TestFetchMultiWhenOnlyOneOfKeysExists() { | ||
s.cache.Save("foo", "bar", 0) | ||
s.cache.Save("foo", "bar", 0) | ||
|
||
result := s.cache.FetchMulti([]string{"foo", "alice"}) | ||
result := s.cache.FetchMulti([]string{"foo", "alice"}) | ||
|
||
s.assert.Len(result, 1) | ||
s.assert.Len(result, 1) | ||
} | ||
|
||
func TestChainRunSuite(t *testing.T) { | ||
suite.Run(t, new(ChainTestSuite)) | ||
suite.Run(t, new(ChainTestSuite)) | ||
} |
Oops, something went wrong.