From 9b83b6565209ec8cb12fad3e144f94e8c7b0d78f Mon Sep 17 00:00:00 2001 From: Matthew Salazar Date: Tue, 12 May 2020 22:43:12 -0400 Subject: [PATCH 1/3] Added custom cache expiration setting; abstracted cache functionality --- CHANGELOG.md | 5 +++++ Makefile | 3 +++ README.md | 10 ++++++++-- cache.go | 38 ++++++++++++++++++++++++++++++++++++++ client.go | 11 ++--------- client_test.go | 18 ++++++++++++++++++ 6 files changed, 74 insertions(+), 11 deletions(-) create mode 100644 cache.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 345878c..ba1fb6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Added +- Settings for cache (pokeapi.CacheSettings) +- Additional testing and documentation for cache settings + ## [1.3.2] / 2020.04.03 ### Added - Current version to README. diff --git a/Makefile b/Makefile index 09280e8..f65a7b9 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,9 @@ deps: tidy vend test: ${GOTEST} -v -race ${CODECOVFLAGS} ./... +test-client: + ${GOTEST} -v ./. + tidy: ${GOMOD} tidy -v diff --git a/README.md b/README.md index f9530b0..daf1d8a 100644 --- a/README.md +++ b/README.md @@ -1000,6 +1000,12 @@ As an alternative to `pokeapi.Resource()`, you can use Search to filter resource ### Caching -Calls are automatically cached to cut down on API traffic to PokeAPI, with subsequent calls (up to five minutes currently) returning local data. You can clear *all* existing cache data with `pokeapi.ClearCache()`. +Calls are automatically cached to cut down on API traffic to PokeAPI, with subsequent calls returning local data. You can clear *all* existing cache data with `pokeapi.ClearCache()`. -Forced non-cached calls and custom cache expiration coming soon. +By default, cache lasts five minutes. You can adjust this by setting `pokeapi.CacheSettings.CustomExpire` to another number, in minutes. For example, to use a twenty-minute cache expiration: + +```go +pokeapi.CacheSettings.CustomExpire = 20 +``` + +Forced non-cached calls coming soon. diff --git a/cache.go b/cache.go new file mode 100644 index 0000000..d63343b --- /dev/null +++ b/cache.go @@ -0,0 +1,38 @@ +package pokeapi + +import "time" + +var CacheSettings = Settings{ + NoCache: false, +} + +var defaultCacheSettings = defaultSettings{ + MaxExpire: 10 * time.Minute, + MinExpire: 5 * time.Minute, +} + +// defaultSettings are settings not meant to be changed. +type defaultSettings struct { + MaxExpire time.Duration + MinExpire time.Duration +} + +// CacheSettings are user settings for cache expiration. +type Settings struct { + CustomExpire time.Duration + NoCache bool +} + +// ClearCache clears all cached data. +func ClearCache() { + c.Flush() +} + +// setCache adds new item to local cache. +func setCache(endpoint string, body []byte) { + if CacheSettings.CustomExpire != 0 { + c.Set(endpoint, body, CacheSettings.CustomExpire * time.Minute) + } else { + c.SetDefault(endpoint, body) + } +} \ No newline at end of file diff --git a/client.go b/client.go index e675d75..c5bebc1 100644 --- a/client.go +++ b/client.go @@ -10,18 +10,11 @@ import ( ) const apiurl = "https://pokeapi.co/api/v2/" -const cachemin = 5 -const cachemax = 10 var c *cache.Cache func init() { - c = cache.New(cachemin*time.Minute, cachemax*time.Minute) -} - -// ClearCache clears all cached data. -func ClearCache() { - c.Flush() + c = cache.New(defaultCacheSettings.MinExpire, defaultCacheSettings.MaxExpire) } func do(endpoint string, obj interface{}) error { @@ -47,6 +40,6 @@ func do(endpoint string, obj interface{}) error { return err } - c.Set(endpoint, body, cache.DefaultExpiration) + setCache(endpoint, body) return json.Unmarshal(body, &obj) } diff --git a/client_test.go b/client_test.go index 6f970cb..db5fc0f 100644 --- a/client_test.go +++ b/client_test.go @@ -3,6 +3,7 @@ package pokeapi import ( "encoding/json" "testing" + "time" "github.com/mtslzr/pokeapi-go/structs" "github.com/stretchr/testify/assert" @@ -49,3 +50,20 @@ func TestClearCache(t *testing.T) { assert.Equal(t, nil, nocache, "Expect no data after flushing cache.") } + +func TestCustomExpiration(t *testing.T) { + ClearCache() + defaultExpire := time.Now().Add(defaultCacheSettings.MinExpire).Minute() + _ = do(endpoint, &mockResource) + _, expires1, _ := c.GetWithExpiration(endpoint) + assert.Equal(t, defaultExpire, expires1.Minute(), + "Expect expiration time to match default setting.") + + CacheSettings.CustomExpire = 20 + customExpire := time.Now().Add(CacheSettings.CustomExpire * time.Minute).Minute() + ClearCache() + _ = do(endpoint, &mockResource) + _, expires2, _ := c.GetWithExpiration(endpoint) + assert.Equal(t, customExpire, expires2.Minute(), + "Expect expiration time to match custom setting.") +} From b9f902a27158bbc7ae5dc75b8eac57a96d4bad4f Mon Sep 17 00:00:00 2001 From: Matthew Salazar Date: Tue, 12 May 2020 23:13:17 -0400 Subject: [PATCH 2/3] Added option for disabling cache --- CHANGELOG.md | 5 +++-- README.md | 29 ++++++++++++++++++++++++++--- cache.go | 5 +++-- client.go | 2 +- client_test.go | 16 +++++++++++++++- 5 files changed, 48 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1fb6c..3a95b59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- Settings for cache (pokeapi.CacheSettings) -- Additional testing and documentation for cache settings +- User settings for caching (pokeapi.CacheSettings) + - CustomExpire: set a custom cache expiration (in minutes) + - UseCache: turn caching on/off ## [1.3.2] / 2020.04.03 ### Added diff --git a/README.md b/README.md index daf1d8a..41934c5 100644 --- a/README.md +++ b/README.md @@ -1000,12 +1000,35 @@ As an alternative to `pokeapi.Resource()`, you can use Search to filter resource ### Caching -Calls are automatically cached to cut down on API traffic to PokeAPI, with subsequent calls returning local data. You can clear *all* existing cache data with `pokeapi.ClearCache()`. +Calls are automatically cached to cut down on API traffic to PokeAPI, with subsequent calls returning local data. -By default, cache lasts five minutes. You can adjust this by setting `pokeapi.CacheSettings.CustomExpire` to another number, in minutes. For example, to use a twenty-minute cache expiration: +#### Clearing Cache ```go +// Clear all existing cache entries. +pokeapi.ClearCache() +``` + +#### Custom Expiration + +Custom cache expiration remains for all calls until changed or unset. + +```go +// Set cache expiration to twenty minutes. pokeapi.CacheSettings.CustomExpire = 20 +// Turn custom expiration back off. +pokeapi.CacheSettings.CustomExpire = 0 ``` -Forced non-cached calls coming soon. +#### Disable Cache + +_Please be considerate of PokeAPI and be sure to always operate within this requested limits._ + +As with custom expiration, this setting remains for all calls until changed or unset. + +```go +// Disable checking for cached data +pokeapi.CacheSettings.UseCache = false +// Re-enable checking for cached data +pokeapi.CacheSettings.UseCache = true +``` diff --git a/cache.go b/cache.go index d63343b..36685eb 100644 --- a/cache.go +++ b/cache.go @@ -3,7 +3,8 @@ package pokeapi import "time" var CacheSettings = Settings{ - NoCache: false, + CustomExpire: 0, + UseCache: true, } var defaultCacheSettings = defaultSettings{ @@ -20,7 +21,7 @@ type defaultSettings struct { // CacheSettings are user settings for cache expiration. type Settings struct { CustomExpire time.Duration - NoCache bool + UseCache bool } // ClearCache clears all cached data. diff --git a/client.go b/client.go index c5bebc1..28dcba0 100644 --- a/client.go +++ b/client.go @@ -19,7 +19,7 @@ func init() { func do(endpoint string, obj interface{}) error { cached, found := c.Get(endpoint) - if found { + if found && CacheSettings.UseCache { return json.Unmarshal(cached.([]byte), &obj) } diff --git a/client_test.go b/client_test.go index db5fc0f..ad4e6af 100644 --- a/client_test.go +++ b/client_test.go @@ -59,11 +59,25 @@ func TestCustomExpiration(t *testing.T) { assert.Equal(t, defaultExpire, expires1.Minute(), "Expect expiration time to match default setting.") + ClearCache() CacheSettings.CustomExpire = 20 customExpire := time.Now().Add(CacheSettings.CustomExpire * time.Minute).Minute() - ClearCache() _ = do(endpoint, &mockResource) _, expires2, _ := c.GetWithExpiration(endpoint) assert.Equal(t, customExpire, expires2.Minute(), "Expect expiration time to match custom setting.") } + +func TestNoCache(t *testing.T) { + ClearCache() + _ = do(endpoint, &mockResource) + _, expires1, found1 := c.GetWithExpiration(endpoint) + assert.Equal(t, true, found1, + "Expect to have cached data after first call.") + + CacheSettings.NoCache = true + _ = do(endpoint, &mockResource) + _, expires2, _ := c.GetWithExpiration(endpoint) + assert.NotEqual(t, expires1, expires2, + "Expect cache expiration not to match first call.") +} From 1353ccdb3eeb46351e01aac760c8e5caa8c373ff Mon Sep 17 00:00:00 2001 From: Matthew Salazar Date: Tue, 12 May 2020 23:14:48 -0400 Subject: [PATCH 3/3] Fixed unit test for disabling cache --- client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client_test.go b/client_test.go index ad4e6af..f8ae1fd 100644 --- a/client_test.go +++ b/client_test.go @@ -75,7 +75,7 @@ func TestNoCache(t *testing.T) { assert.Equal(t, true, found1, "Expect to have cached data after first call.") - CacheSettings.NoCache = true + CacheSettings.UseCache = false _ = do(endpoint, &mockResource) _, expires2, _ := c.GetWithExpiration(endpoint) assert.NotEqual(t, expires1, expires2,