Added page cache middleware.

This commit is contained in:
mikestefanello 2021-12-07 21:36:57 -05:00
parent 855d67409f
commit 30dced6315
6 changed files with 80 additions and 17 deletions

View file

@ -13,6 +13,9 @@ import (
"goweb/config"
"goweb/container"
"goweb/funcmap"
"goweb/middleware"
"github.com/eko/gocache/v2/marshaler"
"github.com/eko/gocache/v2/store"
@ -48,7 +51,7 @@ func NewController(c *container.Container) Controller {
func (t *Controller) RenderPage(c echo.Context, p Page) error {
if p.Name == "" {
c.Logger().Error("Page render failed due to missing name")
c.Logger().Error("page render failed due to missing name")
return echo.NewHTTPError(http.StatusInternalServerError, "Internal server error")
}
@ -65,12 +68,17 @@ func (t *Controller) RenderPage(c echo.Context, p Page) error {
return err
}
t.cachePage(c, p)
t.cachePage(c, p, buf)
// Set any headers
for k, v := range p.Headers {
c.Response().Header().Set(k, v)
}
return c.HTMLBlob(p.StatusCode, buf.Bytes())
}
func (t *Controller) cachePage(c echo.Context, p Page) {
func (t *Controller) cachePage(c echo.Context, p Page, html *bytes.Buffer) {
if !p.Cache.Enabled {
return
}
@ -84,12 +92,19 @@ func (t *Controller) cachePage(c echo.Context, p Page) {
Expiration: p.Cache.MaxAge,
Tags: p.Cache.Tags,
}
err := t.Container.Cache.Set(c.Request().Context(), key, "my-value", opts)
cp := middleware.CachedPage{
HTML: html.Bytes(),
Headers: p.Headers,
StatusCode: p.StatusCode,
}
err := marshaler.New(t.Container.Cache).Set(c.Request().Context(), key, cp, opts)
if err != nil {
c.Logger().Errorf("Failed to cache page: %s", key)
c.Logger().Errorf("failed to cache page: %s", key)
c.Logger().Error(err)
return
}
c.Logger().Infof("cached page for: %s", key)
}
func (t *Controller) parsePageTemplates(p Page) error {
@ -124,7 +139,7 @@ func (t *Controller) parsePageTemplates(p Page) error {
func (t *Controller) executeTemplates(c echo.Context, p Page) (*bytes.Buffer, error) {
tmpl, ok := templates.Load(p.Name)
if !ok {
c.Logger().Error("Uncached page template requested")
c.Logger().Error("uncached page template requested")
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Internal server error")
}

View file

@ -33,9 +33,10 @@ type Page struct {
Description string
Keywords []string
}
Pager pager.Pager
CSRF string
Cache struct {
Pager pager.Pager
CSRF string
Headers map[string]string
Cache struct {
Enabled bool
MaxAge time.Duration
Tags []string
@ -49,6 +50,7 @@ func NewPage(c echo.Context) Page {
Path: c.Request().URL.Path,
StatusCode: http.StatusOK,
Pager: pager.NewPager(c, DefaultItemsPerPage),
Headers: make(map[string]string),
}
p.IsHome = p.Path == "/"

View file

@ -7,6 +7,7 @@ import (
"github.com/gorilla/sessions"
"github.com/labstack/echo-contrib/session"
"github.com/labstack/echo/v4"
echomw "github.com/labstack/echo/v4/middleware"
@ -16,6 +17,12 @@ import (
const StaticDir = "static"
func BuildRouter(c *container.Container) {
// Static files with proper cache control
// funcmap.File() should be used in templates to append a cache key to the URL in order to break cache
// after each server restart
c.Web.Group("", middleware.CacheControl(c.Config.Cache.MaxAge.StaticFile)).
Static("/", StaticDir)
// Middleware
c.Web.Use(echomw.RemoveTrailingSlashWithConfig(echomw.TrailingSlashConfig{
RedirectCode: http.StatusMovedPermanently,
@ -24,18 +31,14 @@ func BuildRouter(c *container.Container) {
c.Web.Use(echomw.Recover())
c.Web.Use(echomw.Gzip())
c.Web.Use(echomw.Logger())
c.Web.Use(echomw.TimeoutWithConfig(echomw.TimeoutConfig{
Timeout: c.Config.App.Timeout,
}))
c.Web.Use(middleware.PageCache(c.Cache))
c.Web.Use(session.Middleware(sessions.NewCookieStore([]byte(c.Config.App.EncryptionKey))))
c.Web.Use(echomw.CSRFWithConfig(echomw.CSRFConfig{
TokenLookup: "form:csrf",
}))
c.Web.Use(echomw.TimeoutWithConfig(echomw.TimeoutConfig{
Timeout: c.Config.App.Timeout,
}))
// Static files with proper cache control
// funcmap.File() should be used in templates to append a cache key to the URL in order to break cache
// after each server restart
c.Web.Group("", middleware.CacheControl(c.Config.Cache.MaxAge.StaticFile)).
Static("/", StaticDir)
// Base controller
ctr := NewController(c)