gosora/experimental/plugin_hyperdrive.go
Azareal e3e5d62e94 Hyperdrive should take Online User widget changes into account now.
The Online Users widget now avoids rebuilding when the users haven't changed.
The Online Users widget cache should actually work now...

Added the tasks_tick_widget_wol plugin hook.
2019-04-20 22:49:48 +10:00

110 lines
2.6 KiB
Go

// Highly experimental plugin for caching rendered pages for guests
package main
import (
//"log"
"bytes"
"sync/atomic"
"net/http"
"net/http/httptest"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/routes"
)
var hyperspace *Hyperspace
func init() {
c.Plugins.Add(&c.Plugin{UName: "hyperdrive", Name: "Hyperdrive", Author: "Azareal", Init: initHdrive, Deactivate: deactivateHdrive})
}
func initHdrive(plugin *c.Plugin) error {
hyperspace = newHyperspace()
plugin.AddHook("tasks_tick_topic_list",tickHdrive)
plugin.AddHook("tasks_tick_widget_wol",tickHdriveWol)
plugin.AddHook("route_topic_list_start",jumpHdrive)
return nil
}
func deactivateHdrive(plugin *c.Plugin) {
plugin.RemoveHook("tasks_tick_topic_list",tickHdrive)
plugin.RemoveHook("tasks_tick_widget_wol",tickHdriveWol)
plugin.RemoveHook("route_topic_list_start",jumpHdrive)
hyperspace = nil
}
type Hyperspace struct {
topicList atomic.Value
}
func newHyperspace() *Hyperspace {
pageCache := new(Hyperspace)
pageCache.topicList.Store([]byte(""))
return pageCache
}
func tickHdriveWol(args ...interface{}) (skip bool, rerr c.RouteError) {
c.DebugLog("docking at wol")
return tickHdrive(args)
}
// TODO: Find a better way of doing this
func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) {
c.DebugLog("Refueling...")
w := httptest.NewRecorder()
req := httptest.NewRequest("get", "/topics/", bytes.NewReader(nil))
user := c.GuestUser
head, err := c.UserCheck(w, req, &user)
if err != nil {
c.LogWarning(err)
return true, rerr
}
rerr = routes.TopicList(w, req, user, head)
if rerr != nil {
c.LogWarning(err)
return true, rerr
}
if w.Code != 200 {
c.LogWarning(err)
}
buf := new(bytes.Buffer)
buf.ReadFrom(w.Result().Body)
hyperspace.topicList.Store(buf.Bytes())
return false, nil
}
func jumpHdrive(args ...interface{}) (skip bool, rerr c.RouteError) {
tList := hyperspace.topicList.Load().([]byte)
if len(tList) == 0 {
c.DebugLog("no topiclist in hyperspace")
return false, nil
}
// Avoid intercepting user requests as we only have guests in cache right now
user := args[2].(*c.User)
if user.ID != 0 {
c.DebugLog("not guest")
return false, nil
}
// Avoid intercepting search requests and filters as we don't have those in cache
r := args[1].(*http.Request)
//c.DebugLog("r.URL.Path:",r.URL.Path)
//c.DebugLog("r.URL.RawQuery:",r.URL.RawQuery)
if r.URL.RawQuery != "" {
return false, nil
}
//c.DebugLog
c.DebugLog("Successful jump")
w := args[0].(http.ResponseWriter)
header := args[3].(*c.Header)
routes.FootHeaders(w, header)
w.Write(tList)
return true, nil
}