benoitdm-oslandia / pg_featureserv

Apache License 2.0
1 stars 0 forks source link

Task - create a version of the cache shared between servers and based on redis #78

Closed benoitdm-oslandia closed 1 year ago

benoitdm-oslandia commented 2 years ago

Créer un cache exploitant redis

Dans le cas d'un déploiement avec une scalabilité horizontale, le cache sera différent d'une instance à l'autre. Pour palier à ce problème, on peut utiliser une instance Redis qui fera le stockage du cache !

Liens utiles (lecture)

Étapes

  1. [ ] Installer au préalable un serveur Redis

    Mise en place externe au projet

  2. [ ] Ajouter une option du processus ou une variable d'env pour activer l'utilisation du cache Redis

  3. [ ] Ajouter la configuration Redis (toml)

  4. [ ] Initialiser la connexion Redis

  5. [ ] Mettre en place une logique d’implémentation

    [GET] :
    si la donnée n'est pas disponible dans le cache Redis,

    • on va la chercher en base
    • on l'enregistre dans le cache Redis

    1_tAvBvnbFK_MkEfHj_ViQMQ

    [GET] :
    si la donnée n'est pas disponible ni dans le cache Redis, ni en base, on enregistre l'information de non-existence dans le cache Redis

    1_5ZAZg47q-V2aEbHnt_UByw

    [POST] :
    on enregistre toujours les nouvelles données dans le cache Redis

    [PATCH | PUT] :
    on enregistre la modification de données dans le cache Redis, en écrasant l'ancien cache

    :eye_in_speech_bubble: Redis stocke des clefs/valeurs

    • Ex. etag: {...} // réponse json d'une collection

    :eye_in_speech_bubble: où ajouter les instructions redis ?

    on va utiliser la notion de middleware !

  6. [ ] Implémenter le middleware

    • [ ] vérifier : verifyRedis()
    • [ ] enregistrer : setRedis()
    • [ ] récupérer : getRedis()
    • [ ] nettoyer : clearRedis()

    cf. commentaire : exemples d'implémentation

  7. [ ] Ajouter un test d'utilisation du cache Redis

  8. [ ] Mettre en place un benchmark avec / sans cache Redis

  9. [ ] Test de charge

    Mise en place interne au projet

    • [ ] Installer K6

      https://github.com/grafana/k6

    • [ ] Ecrire les tests K6

    • [ ] Mettre en place dans la CI

    • [ ] Visualisation des résultats dans K6 Cloud

benoitdm-oslandia commented 1 year ago

In GitLab by @lowzonenose on Nov 1, 2022, 10:10

changed time estimate to 120h

benoitdm-oslandia commented 1 year ago

In GitLab by @lowzonenose on Nov 1, 2022, 20:50

Exemple d'implémentation du cache Redis en middleware

func addRouteWithMethod(router mux.Router, path string, handler func(http.ResponseWriter, http.Request) *appError, method string) { router.Handle(path, appHandler(handler)).Methods(method) }

type appHandler func(http.ResponseWriter, http.Request) appError

// middleware func MiddlewareRedis(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // logique du cache redis : // > Redis Actif ? // > renvoie un cache (GetRedis(something)) ou redirige vers le handler (next) next.ServeHTTP(w, r) }) }

// handler func handler(w http.ResponseWriter, r http.Request) appError { // logique de la reponse : // > renvoie une reponse de la bdd // > Redis Actif ? // > creer une entrée dans le cache -> setRedis(something) }


* Ex. Request POST : 
> - aucune modifiation des signatures
> - chaque handler possède le code Redis -> SetRedis(something)
```go
func addRouteWithMethod(router *mux.Router, path string, handler func(http.ResponseWriter, *http.Request) *appError, method string) {
    router.Handle(path, appHandler(handler)).Methods(method)
}

// handler
func handler(w http.ResponseWriter, r *http.Request) *appError {
  // logique de la reponse : 
  // > renvoie une reponse de la bdd
  // > Redis Actif ?
  // >   creer une entrée dans le cache -> SetRedis(something)
}

// handler func handler(w http.ResponseWriter, r http.Request) appError { if data := r.Context().Value("data"); data != nil { // some stuff... } }

benoitdm-oslandia commented 1 year ago

In GitLab by @lowzonenose on Nov 1, 2022, 20:52

added 8h of time spent

benoitdm-oslandia commented 1 year ago

In GitLab by @lowzonenose on Nov 2, 2022, 24:33

Autre exemple d'implémentation du cache Redis en middleware

// middleware sur toutes les routes
func addRouteWithMethod(router *mux.Router, path string, handler func(http.ResponseWriter, *http.Request) *appError, method string) {
  router.Handle(path, appHandler(handler)).Methods(method)
  router.Use(redis.Middleware)
}

// middleware
func (c *CacheRedis) Middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // logique du cache redis : 
        // > Redis Actif ?
        // > renvoie un cache (getRedis(something)) ou redirige vers le handler (next)
        next.ServeHTTP(w, r)
    })
}
type CacheRedis struct {...}
func redisConnect() CacheRedis {} 
func redisConfig() {}
func (c *CacheRedis) Set () {}
func (c *CacheRedis) Get () {}
func (c *CacheRedis) Active () {}
func (c *CacheRedis) Middleware () {}
(...)
benoitdm-oslandia commented 1 year ago

hum ... il faut qu'on parle @lowzonenose :smile:

benoitdm-oslandia commented 1 year ago

marked this issue as related to #11

benoitdm-oslandia commented 1 year ago

cloned to #89

benoitdm-oslandia commented 1 year ago

marked this issue as related to #89