Make UI plugins much more memory efficient by using io.Pipe and add methods to the post plugintype

This commit is contained in:
Jan-Lukas Else 2023-01-23 20:25:45 +01:00
parent 0f14d71ad3
commit aa9b1996a2
4 changed files with 68 additions and 20 deletions

View File

@ -25,8 +25,16 @@ type Database interface {
// Post
type Post interface {
// Get the post path
GetPath() string
// Get a string array map with all the post's parameters
GetParameters() map[string][]string
// Get the post section name
GetSection() string
// Get the published date string
GetPublished() string
// Get the updated date string
GetUpdated() string
}
// RenderContext

View File

@ -131,11 +131,27 @@ func (W _go_goblog_app_app_pkgs_plugintypes_Middleware) Prio() int {
type _go_goblog_app_app_pkgs_plugintypes_Post struct {
IValue interface{}
WGetParameters func() map[string][]string
WGetPath func() string
WGetPublished func() string
WGetSection func() string
WGetUpdated func() string
}
func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetParameters() map[string][]string {
return W.WGetParameters()
}
func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetPath() string {
return W.WGetPath()
}
func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetPublished() string {
return W.WGetPublished()
}
func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetSection() string {
return W.WGetSection()
}
func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetUpdated() string {
return W.WGetUpdated()
}
// _go_goblog_app_app_pkgs_plugintypes_RenderContext is an interface wrapper for RenderContext type
type _go_goblog_app_app_pkgs_plugintypes_RenderContext struct {

View File

@ -78,6 +78,22 @@ func (a *goBlog) GetPost(path string) (plugintypes.Post, error) {
return a.getPost(path)
}
func (p *post) GetPath() string {
return p.Path
}
func (p *post) GetParameters() map[string][]string {
return p.Parameters
}
func (p *post) GetSection() string {
return p.Section
}
func (p *post) GetPublished() string {
return p.Published
}
func (p *post) GetUpdated() string {
return p.Updated
}

View File

@ -4,7 +4,6 @@ import (
"io"
"net/http"
"go.goblog.app/app/pkgs/bufferpool"
"go.goblog.app/app/pkgs/contenttype"
"go.goblog.app/app/pkgs/htmlbuilder"
"go.goblog.app/app/pkgs/plugintypes"
@ -41,26 +40,35 @@ func (a *goBlog) renderWithStatusCode(w http.ResponseWriter, r *http.Request, st
// Write status code
w.WriteHeader(statusCode)
// Render
buf := bufferpool.Get()
defer bufferpool.Put(buf)
f(htmlbuilder.NewHtmlBuilder(buf), data)
// Check if UI plugins are registered
uiPlugins := a.getPlugins(pluginUiType)
if len(uiPlugins) > 0 {
pluginBuf := bufferpool.Get()
defer bufferpool.Put(pluginBuf)
for _, plug := range uiPlugins {
pluginBuf.Reset()
plug.(plugintypes.UI).Render(&pluginRenderContext{
blog: data.BlogString,
path: r.URL.Path,
}, buf, pluginBuf)
buf.Reset()
_, _ = io.Copy(buf, pluginBuf)
}
}
renderPipeReader, renderPipeWriter := io.Pipe()
go func() {
f(htmlbuilder.NewHtmlBuilder(renderPipeWriter), data)
renderPipeWriter.Close()
}()
// Run UI plugins
pluginPipeReader, pluginPipeWriter := io.Pipe()
go func() {
a.chainUiPlugins(a.getPlugins(pluginUiType), &pluginRenderContext{
blog: data.BlogString,
path: r.URL.Path,
}, renderPipeReader, pluginPipeWriter)
pluginPipeWriter.Close()
}()
// Return minified HTML
_ = a.min.Get().Minify(contenttype.HTML, w, buf)
_ = a.min.Get().Minify(contenttype.HTML, w, pluginPipeReader)
}
func (a *goBlog) chainUiPlugins(plugins []any, rc *pluginRenderContext, rendered io.Reader, modified io.Writer) {
if len(plugins) == 0 {
_, _ = io.Copy(modified, rendered)
return
}
reader, writer := io.Pipe()
go func() {
plugins[0].(plugintypes.UI).Render(rc, rendered, writer)
_ = writer.Close()
}()
a.chainUiPlugins(plugins[1:], rc, reader, modified)
}
func (a *goBlog) checkRenderData(r *http.Request, data *renderData) {