Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(chore): allow chained storages #359

Merged
merged 3 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/non-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
workflow_dispatch:

env:
GO_VERSION: '1.20'
GO_VERSION: '1.21'

jobs:
lint-validation:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/plugins-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- master

env:
GO_VERSION: '1.20'
GO_VERSION: '1.21'

jobs:
build-caddy-validator:
Expand Down
34 changes: 17 additions & 17 deletions .github/workflows/plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
name: Install Go
uses: actions/setup-go@v3
with:
go-version: '1.20'
go-version: '1.21'
-
name: Checkout code
uses: actions/checkout@v3
Expand Down Expand Up @@ -81,124 +81,124 @@ jobs:
with:
CAPITALIZED_NAME: Beego
LOWER_NAME: beego
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-chi-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Chi
LOWER_NAME: chi
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-dotweb-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Dotweb
LOWER_NAME: dotweb
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-echo-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Echo
LOWER_NAME: echo
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-fiber-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Fiber
LOWER_NAME: fiber
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-gin-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Gin
LOWER_NAME: gin
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-goa-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Goa
LOWER_NAME: goa
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-go-zero-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Go-zero
LOWER_NAME: go-zero
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-hertz-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Hertz
LOWER_NAME: hertz
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-kratos-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Kratos
LOWER_NAME: kratos
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-roadrunner-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Roadrunner
LOWER_NAME: roadrunner
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-skipper-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Skipper
LOWER_NAME: skipper
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-souin-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Souin
LOWER_NAME: souin
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-traefik-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Traefik
LOWER_NAME: traefik
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-tyk-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Tyk
LOWER_NAME: tyk
GO_VERSION: '1.20'
GO_VERSION: '1.21'
build-webgo-validator:
name: Check that Souin build as middleware
uses: ./.github/workflows/plugin_template.yml
secrets: inherit
with:
CAPITALIZED_NAME: Webgo
LOWER_NAME: webgo
GO_VERSION: '1.20'
GO_VERSION: '1.21'
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
tags: ["v*"]

env:
GO_VERSION: '1.20'
GO_VERSION: '1.21'

jobs:
generate-souin-traefik-docker:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/workflow_plugins_generator.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

plugins=("beego" "chi" "dotweb" "echo" "fiber" "gin" "goa" "go-zero" "hertz" "kratos" "roadrunner" "skipper" "souin" "traefik" "tyk" "webgo")
go_version=1.20
go_version=1.21

IFS= read -r -d '' tpl <<EOF
name: Build and validate Souin as plugins
Expand Down
7 changes: 7 additions & 0 deletions configurationtypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ type DefaultCache struct {
Port Port `json:"port" yaml:"port"`
Regex Regex `json:"regex" yaml:"regex"`
Stale Duration `json:"stale" yaml:"stale"`
Storers []string `json:"storers" yaml:"storers"`
Timeout Timeout `json:"timeout" yaml:"timeout"`
TTL Duration `json:"ttl" yaml:"ttl"`
DefaultCacheControl string `json:"default_cache_control" yaml:"default_cache_control"`
Expand Down Expand Up @@ -314,6 +315,11 @@ func (d *DefaultCache) GetStale() time.Duration {
return d.Stale.Duration
}

// GetStale returns the stale duration
func (d *DefaultCache) GetStorers() []string {
return d.Storers
}

// GetDefaultCacheControl returns the default Cache-Control response header value when empty
func (d *DefaultCache) GetDefaultCacheControl() string {
return d.DefaultCacheControl
Expand All @@ -335,6 +341,7 @@ type DefaultCacheInterface interface {
GetKey() Key
GetRegex() Regex
GetStale() time.Duration
GetStorers() []string
GetTimeout() Timeout
GetTTL() time.Duration
GetDefaultCacheControl() string
Expand Down
8 changes: 4 additions & 4 deletions pkg/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type MapHandler struct {
// GenerateHandlerMap generate the MapHandler
func GenerateHandlerMap(
configuration configurationtypes.AbstractConfigurationInterface,
storer storage.Storer,
storers []storage.Storer,
surrogateStorage providers.SurrogateInterface,
) *MapHandler {
hm := make(map[string]http.HandlerFunc)
Expand All @@ -30,7 +30,7 @@ func GenerateHandlerMap(
basePathAPIS = "/souin-api"
}

for _, endpoint := range Initialize(configuration, storer, surrogateStorage) {
for _, endpoint := range Initialize(configuration, storers, surrogateStorage) {
if endpoint.IsEnabled() {
shouldEnable = true
hm[basePathAPIS+endpoint.GetBasePath()] = endpoint.HandleRequest
Expand All @@ -45,7 +45,7 @@ func GenerateHandlerMap(
}

// Initialize contains all apis that should be enabled
func Initialize(c configurationtypes.AbstractConfigurationInterface, storer storage.Storer, surrogateStorage providers.SurrogateInterface) []EndpointInterface {
return []EndpointInterface{initializeSouin(c, storer,
func Initialize(c configurationtypes.AbstractConfigurationInterface, storers []storage.Storer, surrogateStorage providers.SurrogateInterface) []EndpointInterface {
return []EndpointInterface{initializeSouin(c, storers,
surrogateStorage), debug.InitializeDebug(c), prometheus.InitializePrometheus(c)}
}
29 changes: 21 additions & 8 deletions pkg/api/souin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import (
type SouinAPI struct {
basePath string
enabled bool
storer storage.Storer
storers []storage.Storer
surrogateStorage providers.SurrogateInterface
}

func initializeSouin(
configuration configurationtypes.AbstractConfigurationInterface,
storer storage.Storer,
storers []storage.Storer,
surrogateStorage providers.SurrogateInterface,
) *SouinAPI {
basePath := configuration.GetAPI().Souin.BasePath
Expand All @@ -31,24 +31,33 @@ func initializeSouin(
return &SouinAPI{
basePath,
configuration.GetAPI().Souin.Enable,
storer,
storers,
surrogateStorage,
}
}

// BulkDelete allow user to delete multiple items with regexp
func (s *SouinAPI) BulkDelete(key string) {
s.storer.DeleteMany(key)
for _, current := range s.storers {
current.DeleteMany(key)
}
}

// Delete will delete a record into the provider cache system and will update the Souin API if enabled
func (s *SouinAPI) Delete(key string) {
s.storer.Delete(key)
for _, current := range s.storers {
current.Delete(key)
}
}

// GetAll will retrieve all stored keys in the provider
func (s *SouinAPI) GetAll() []string {
return s.storer.ListKeys()
keys := []string{}
for _, current := range s.storers {
keys = append(keys, current.ListKeys()...)
}

return keys
}

// GetBasePath will return the basepath for this resource
Expand Down Expand Up @@ -100,7 +109,9 @@ func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) {
flushRg := regexp.MustCompile(s.GetBasePath() + "/flush$")

if flushRg.FindString(r.RequestURI) != "" {
s.storer.DeleteMany(".+")
for _, current := range s.storers {
current.DeleteMany(".+")
}
e := s.surrogateStorage.Destruct()
if e != nil {
fmt.Printf("Error while purging the surrogate keys: %+v.", e)
Expand All @@ -113,7 +124,9 @@ func (s *SouinAPI) HandleRequest(w http.ResponseWriter, r *http.Request) {
} else {
ck, _ := s.surrogateStorage.Purge(r.Header)
for _, k := range ck {
s.storer.Delete(k)
for _, current := range s.storers {
current.Delete(k)
}
}
}
w.WriteHeader(http.StatusNoContent)
Expand Down
Loading
Loading