Skip to content

Commit

Permalink
fix(plugins): Support caddy config reload for embedded olric (#214)
Browse files Browse the repository at this point in the history
* fix(plugins): Support caddy config reload for embedded olric

* Fix linter errors

* Increase goyave waiting time
  • Loading branch information
darkweak committed May 29, 2022
1 parent 8bc4137 commit 960e570
Show file tree
Hide file tree
Showing 18 changed files with 225 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ jobs:
name: Wait for Souin is really loaded inside Goyave as middleware
uses: jakejarvis/wait-action@master
with:
time: 20s
time: 30s
-
name: Set Goyave logs configuration result as environment variable
run: cd plugins/goyave/examples && echo "GOYAVE_MIDDLEWARE_RESULT=$(docker-compose logs goyave | grep Souin)" >> $GITHUB_ENV
Expand Down
6 changes: 3 additions & 3 deletions cache/providers/badgerProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func BadgerConnectionFactory(c t.AbstractConfigurationInterface) (*Badger, error
fmt.Println("An error occurred during the badgerOptions merge from the default options with your configuration.")
}
} else {
badgerOptions = badgerOptions.WithInMemory(true)
badgerOptions = badgerOptions.WithInMemory(true).WithNumMemtables(1).WithNumLevelZeroTables(1)
}

uid := badgerOptions.Dir + badgerOptions.ValueDir
Expand Down Expand Up @@ -181,6 +181,6 @@ func (provider *Badger) Init() error {
}

// Reset method will reset or close provider
func (provider *Badger) Reset() {
_ = provider.DB.DropAll()
func (provider *Badger) Reset() error {
return provider.DB.DropAll()
}
23 changes: 18 additions & 5 deletions cache/providers/embeddedOlricProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type EmbeddedOlric struct {
dm *olric.DMap
db *olric.Olric
stale time.Duration
ct context.Context
}

func tryToLoadConfiguration(olricInstance *config.Config, olricConfiguration t.CacheProvider, logger *zap.Logger) (*config.Config, bool) {
Expand Down Expand Up @@ -82,11 +83,11 @@ func EmbeddedOlricConnectionFactory(configuration t.AbstractConfigurationInterfa
defer func() {
close(ch)
}()
go func() {
if err = db.Start(); err != nil {
go func(currDB *olric.Olric) {
if err = currDB.Start(); err != nil {
ch <- err
}
}()
}(db)

select {
case err = <-ch:
Expand All @@ -100,6 +101,7 @@ func EmbeddedOlricConnectionFactory(configuration t.AbstractConfigurationInterfa
dm: dm,
db: db,
stale: configuration.GetDefaultCache().GetStale(),
ct: context.Background(),
}, e
}

Expand Down Expand Up @@ -231,6 +233,17 @@ func (provider *EmbeddedOlric) Init() error {
}

// Reset method will reset or close provider
func (provider *EmbeddedOlric) Reset() {
_ = provider.db.Shutdown(context.Background())
func (provider *EmbeddedOlric) Reset() error {
return provider.db.Shutdown(provider.ct)
}

// Destruct method will reset or close provider
func (provider *EmbeddedOlric) Destruct() error {
fmt.Println("Destruct current embedded olric...")
return provider.Reset()
}

// GetDM method returns the embbeded instance dm property
func (provider *EmbeddedOlric) GetDM() *olric.DMap {
return provider.dm
}
32 changes: 24 additions & 8 deletions cache/providers/embeddedOlricProvider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ func getEmbeddedOlricWithoutYAML(key string) (types.AbstractProviderInterface, c

func TestIShouldBeAbleToReadAndWriteDataInEmbeddedOlric(t *testing.T) {
client, u := getEmbeddedOlricClientAndMatchedURL("Test")
defer client.Reset()
defer func() {
_ = client.Reset()
}()
client.Set("Test", []byte(EMBEDDEDOLRICVALUE), u, time.Duration(10)*time.Second)
time.Sleep(3 * time.Second)
res := client.Get("Test")
Expand All @@ -49,7 +51,9 @@ func TestIShouldBeAbleToReadAndWriteDataInEmbeddedOlric(t *testing.T) {

func TestIShouldBeAbleToReadAndWriteDataInEmbeddedOlricWithoutYAML(t *testing.T) {
client, u := getEmbeddedOlricWithoutYAML("Test")
defer client.Reset()
defer func() {
_ = client.Reset()
}()
client.Set("Test", []byte(EMBEDDEDOLRICVALUE), u, time.Duration(10)*time.Second)
time.Sleep(3 * time.Second)
res := client.Get("Test")
Expand All @@ -60,7 +64,9 @@ func TestIShouldBeAbleToReadAndWriteDataInEmbeddedOlricWithoutYAML(t *testing.T)

func TestEmbeddedOlric_GetRequestInCache(t *testing.T) {
client, _ := getEmbeddedOlricClientAndMatchedURL(NONEXISTENTKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
res := client.Get(NONEXISTENTKEY)
if string(res) != "" {
errors.GenerateError(t, fmt.Sprintf("Key %s should not exist", NONEXISTENTKEY))
Expand All @@ -69,28 +75,36 @@ func TestEmbeddedOlric_GetRequestInCache(t *testing.T) {

func TestEmbeddedOlric_SetRequestInCache_OneByte(t *testing.T) {
client, u := getEmbeddedOlricClientAndMatchedURL(BYTEKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
client.Set(BYTEKEY, []byte{65}, u, time.Duration(20)*time.Second)
}

func TestEmbeddedOlric_SetRequestInCache_TTL(t *testing.T) {
key := "MyEmptyKey"
client, matchedURL := getEmbeddedOlricClientAndMatchedURL(key)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
nv := []byte("Hello world")
setValueThenVerify(client, key, nv, matchedURL, time.Duration(20)*time.Second, t)
}

func TestEmbeddedOlric_SetRequestInCache_NoTTL(t *testing.T) {
client, matchedURL := getEmbeddedOlricClientAndMatchedURL(BYTEKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
nv := []byte("New value")
setValueThenVerify(client, BYTEKEY, nv, matchedURL, 0, t)
}

func TestEmbeddedOlric_DeleteRequestInCache(t *testing.T) {
client, _ := getEmbeddedOlricClientAndMatchedURL(BYTEKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
client.Delete(BYTEKEY)
time.Sleep(1 * time.Second)
if 0 < len(client.Get(BYTEKEY)) {
Expand All @@ -101,7 +115,9 @@ func TestEmbeddedOlric_DeleteRequestInCache(t *testing.T) {
func TestEmbeddedOlric_Init(t *testing.T) {
client, _ := EmbeddedOlricConnectionFactory(tests.MockConfiguration(tests.EmbeddedOlricConfiguration))
err := client.Init()
defer client.Reset()
defer func() {
_ = client.Reset()
}()

if nil != err {
errors.GenerateError(t, "Impossible to init EmbeddedOlric provider")
Expand Down
4 changes: 3 additions & 1 deletion cache/providers/olricProvider.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ func (provider *Olric) Init() error {
}

// Reset method will reset or close provider
func (provider *Olric) Reset() {
func (provider *Olric) Reset() error {
provider.Client.Close()

return nil
}
28 changes: 21 additions & 7 deletions cache/providers/olricProvider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ func getOlricClientAndMatchedURL(key string) (types.AbstractProviderInterface, c

func TestIShouldBeAbleToReadAndWriteDataInOlric(t *testing.T) {
client, u := getOlricClientAndMatchedURL("Test")
defer client.Reset()
defer func() {
_ = client.Reset()
}()
client.Set("Test", []byte(OLRICVALUE), u, time.Duration(10)*time.Second)
time.Sleep(3 * time.Second)
res := client.Get("Test")
Expand All @@ -42,7 +44,9 @@ func TestIShouldBeAbleToReadAndWriteDataInOlric(t *testing.T) {

func TestOlric_GetRequestInCache(t *testing.T) {
client, _ := getOlricClientAndMatchedURL(NONEXISTENTKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
res := client.Get(NONEXISTENTKEY)
if string(res) != "" {
errors.GenerateError(t, fmt.Sprintf("Key %s should not exist", NONEXISTENTKEY))
Expand All @@ -51,28 +55,36 @@ func TestOlric_GetRequestInCache(t *testing.T) {

func TestOlric_SetRequestInCache_OneByte(t *testing.T) {
client, u := getOlricClientAndMatchedURL(BYTEKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
client.Set(BYTEKEY, []byte{65}, u, time.Duration(20)*time.Second)
}

func TestOlric_SetRequestInCache_TTL(t *testing.T) {
key := "MyEmptyKey"
client, matchedURL := getOlricClientAndMatchedURL(key)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
nv := []byte("Hello world")
setValueThenVerify(client, key, nv, matchedURL, time.Duration(20)*time.Second, t)
}

func TestOlric_SetRequestInCache_NoTTL(t *testing.T) {
client, matchedURL := getOlricClientAndMatchedURL(BYTEKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
nv := []byte("New value")
setValueThenVerify(client, BYTEKEY, nv, matchedURL, 0, t)
}

func TestOlric_DeleteRequestInCache(t *testing.T) {
client, _ := getOlricClientAndMatchedURL(BYTEKEY)
defer client.Reset()
defer func() {
_ = client.Reset()
}()
client.Delete(BYTEKEY)
time.Sleep(1 * time.Second)
if 0 < len(client.Get(BYTEKEY)) {
Expand All @@ -83,7 +95,9 @@ func TestOlric_DeleteRequestInCache(t *testing.T) {
func TestOlric_Init(t *testing.T) {
client, _ := OlricConnectionFactory(tests.MockConfiguration(tests.OlricConfiguration))
err := client.Init()
defer client.Reset()
defer func() {
_ = client.Reset()
}()

if nil != err {
errors.GenerateError(t, "Impossible to init Olric provider")
Expand Down
2 changes: 1 addition & 1 deletion cache/types/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ type AbstractProviderInterface interface {
Delete(key string)
DeleteMany(key string)
Init() error
Reset()
Reset() error
}
2 changes: 2 additions & 0 deletions plugins/caddy/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ func (s *SouinApp) Provision(_ caddy.Context) error {

// Start will start the App
func (s SouinApp) Start() error {
up.Delete(stored_providers_key)
up.LoadOrStore(stored_providers_key, newStorageProvider())
if s.DefaultCache != nil && s.DefaultCache.GetTTL() == 0 {
return errors.New("Invalid/Incomplete default cache declaration")
}
Expand Down
51 changes: 51 additions & 0 deletions plugins/caddy/cleaner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package httpcache

import (
"fmt"
"sync"
)

const stored_providers_key = "STORED_PROVIDERS_KEY"

type storage_providers struct {
list map[interface{}]bool
sync.RWMutex
}

func newStorageProvider() *storage_providers {
return &storage_providers{
list: make(map[interface{}]bool),
RWMutex: sync.RWMutex{},
}
}

func (s *storage_providers) Add(key interface{}) {
s.RWMutex.Lock()
defer s.RWMutex.Unlock()

s.list[key] = true
}

func (s *SouinCaddyPlugin) Cleanup() error {
fmt.Println("Cleanup...")
td := []interface{}{}
sp, _ := up.LoadOrStore(stored_providers_key, newStorageProvider())
stored_providers := sp.(*storage_providers)
fmt.Println(stored_providers.list)
up.Range(func(key, value interface{}) bool {
if key != stored_providers_key {
if !stored_providers.list[key] {
td = append(td, key)
}
}

return true
})

for _, v := range td {
fmt.Printf("Cleaning %v\n", v)
up.Delete(v)
}

return nil
}
2 changes: 1 addition & 1 deletion plugins/caddy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/darkweak/souin/plugins/caddy
go 1.17

require (
github.com/buraksezer/olric v0.4.2
github.com/caddyserver/caddy/v2 v2.5.0
github.com/darkweak/souin v1.6.8
go.uber.org/zap v1.21.0
Expand All @@ -22,7 +23,6 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/buraksezer/connpool v0.4.0 // indirect
github.com/buraksezer/consistent v0.0.0-20191006190839-693edf70fd72 // indirect
github.com/buraksezer/olric v0.4.2 // indirect
github.com/caddyserver/certmagic v0.16.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
Expand Down
Loading

0 comments on commit 960e570

Please sign in to comment.