Hyperdrive now caches /forums/ too.

Added the route_forum_list_start plugin hook.
This commit is contained in:
Azareal 2019-04-28 20:50:45 +10:00
parent efe7a0f3f0
commit bd7b1681e3
4 changed files with 59 additions and 8 deletions

View File

@ -84,6 +84,7 @@ var hookTable = &HookTable{
"forum_check_pre_perms": nil, "forum_check_pre_perms": nil,
"route_topic_list_start": nil, "route_topic_list_start": nil,
"route_forum_list_start": nil,
"action_end_create_topic": nil, "action_end_create_topic": nil,
"action_end_edit_topic":nil, "action_end_edit_topic":nil,

View File

@ -219,9 +219,9 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
// An optimisation so we don't populate StartedAt for users who shouldn't see the stat anyway // An optimisation so we don't populate StartedAt for users who shouldn't see the stat anyway
// ? - Should we only show this in debug mode? It might be useful for detecting issues in production, if we show it there as-well // ? - Should we only show this in debug mode? It might be useful for detecting issues in production, if we show it there as-well
if user.IsAdmin { //if user.IsAdmin {
header.StartedAt = time.Now() header.StartedAt = time.Now()
} //}
//PrepResources(user,header,theme) //PrepResources(user,header,theme)
return header, nil return header, nil

View File

@ -26,20 +26,24 @@ func initHdrive(plugin *c.Plugin) error {
hyperspace = newHyperspace() hyperspace = newHyperspace()
plugin.AddHook("tasks_tick_topic_list",tickHdrive) plugin.AddHook("tasks_tick_topic_list",tickHdrive)
plugin.AddHook("tasks_tick_widget_wol",tickHdriveWol) plugin.AddHook("tasks_tick_widget_wol",tickHdriveWol)
plugin.AddHook("route_topic_list_start",jumpHdrive) plugin.AddHook("route_topic_list_start",jumpHdriveTopicList)
plugin.AddHook("route_forum_list_start",jumpHdriveForumList)
return nil return nil
} }
func deactivateHdrive(plugin *c.Plugin) { func deactivateHdrive(plugin *c.Plugin) {
plugin.RemoveHook("tasks_tick_topic_list",tickHdrive) plugin.RemoveHook("tasks_tick_topic_list",tickHdrive)
plugin.RemoveHook("tasks_tick_widget_wol",tickHdriveWol) plugin.RemoveHook("tasks_tick_widget_wol",tickHdriveWol)
plugin.RemoveHook("route_topic_list_start",jumpHdrive) plugin.RemoveHook("route_topic_list_start",jumpHdriveTopicList)
plugin.RemoveHook("route_forum_list_start",jumpHdriveForumList)
hyperspace = nil hyperspace = nil
} }
type Hyperspace struct { type Hyperspace struct {
topicList atomic.Value topicList atomic.Value
gzipTopicList atomic.Value gzipTopicList atomic.Value
forumList atomic.Value
gzipForumList atomic.Value
lastTopicListUpdate atomic.Value lastTopicListUpdate atomic.Value
} }
@ -47,6 +51,8 @@ func newHyperspace() *Hyperspace {
pageCache := new(Hyperspace) pageCache := new(Hyperspace)
pageCache.topicList.Store([]byte("")) pageCache.topicList.Store([]byte(""))
pageCache.gzipTopicList.Store([]byte("")) pageCache.gzipTopicList.Store([]byte(""))
pageCache.forumList.Store([]byte(""))
pageCache.gzipForumList.Store([]byte(""))
pageCache.lastTopicListUpdate.Store(int64(0)) pageCache.lastTopicListUpdate.Store(int64(0))
return pageCache return pageCache
} }
@ -63,6 +69,8 @@ func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) {
// Avoid accidentally caching already cached content // Avoid accidentally caching already cached content
hyperspace.topicList.Store([]byte("")) hyperspace.topicList.Store([]byte(""))
hyperspace.gzipTopicList.Store([]byte("")) hyperspace.gzipTopicList.Store([]byte(""))
hyperspace.forumList.Store([]byte(""))
hyperspace.gzipForumList.Store([]byte(""))
w := httptest.NewRecorder() w := httptest.NewRecorder()
req := httptest.NewRequest("get", "/topics/", bytes.NewReader(nil)) req := httptest.NewRequest("get", "/topics/", bytes.NewReader(nil))
@ -92,25 +100,62 @@ func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) {
return false, nil return false, nil
} }
hyperspace.gzipTopicList.Store(gbuf) hyperspace.gzipTopicList.Store(gbuf)
w = httptest.NewRecorder()
req = httptest.NewRequest("get", "/forums/", bytes.NewReader(nil))
user = c.GuestUser
head, rerr = c.UserCheck(w, req, &user)
if rerr != nil {
return true, rerr
}
rerr = routes.ForumList(w, req, user, head)
if rerr != nil {
return true, rerr
}
if w.Code != 200 {
c.LogWarning(errors.New("not 200 for forum list in hyperdrive"))
return false, nil
}
buf = new(bytes.Buffer)
buf.ReadFrom(w.Result().Body)
hyperspace.forumList.Store(buf.Bytes())
gbuf, err = c.CompressBytesGzip(buf.Bytes())
if err != nil {
c.LogWarning(err)
return false, nil
}
hyperspace.gzipForumList.Store(gbuf)
hyperspace.lastTopicListUpdate.Store(time.Now().Unix()) hyperspace.lastTopicListUpdate.Store(time.Now().Unix())
return false, nil return false, nil
} }
func jumpHdrive(args ...interface{}) (skip bool, rerr c.RouteError) { func jumpHdriveTopicList(args ...interface{}) (skip bool, rerr c.RouteError) {
return jumpHdrive(hyperspace.gzipTopicList.Load().([]byte), hyperspace.topicList.Load().([]byte), args)
}
func jumpHdriveForumList(args ...interface{}) (skip bool, rerr c.RouteError) {
return jumpHdrive(hyperspace.gzipForumList.Load().([]byte), hyperspace.forumList.Load().([]byte), args)
}
func jumpHdrive(pg []byte, p []byte, args []interface{}) (skip bool, rerr c.RouteError) {
var tList []byte var tList []byte
w := args[0].(http.ResponseWriter) w := args[0].(http.ResponseWriter)
var iw http.ResponseWriter var iw http.ResponseWriter
gzw, ok := w.(c.GzipResponseWriter) gzw, ok := w.(c.GzipResponseWriter)
if ok { if ok {
tList = hyperspace.gzipTopicList.Load().([]byte) tList = pg
iw = gzw.ResponseWriter iw = gzw.ResponseWriter
} else { } else {
tList = hyperspace.topicList.Load().([]byte) tList = p
iw = w iw = w
} }
if len(tList) == 0 { if len(tList) == 0 {
c.DebugLog("no topiclist in hyperspace") c.DebugLog("no itemlist in hyperspace")
return false, nil return false, nil
} }
//c.DebugLog("tList: ", tList) //c.DebugLog("tList: ", tList)

View File

@ -9,6 +9,11 @@ import (
) )
func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError { func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError {
skip, rerr := header.Hooks.VhookSkippable("route_forum_list_start", w, r, &user, header)
if skip || rerr != nil {
return rerr
}
header.Title = phrases.GetTitlePhrase("forums") header.Title = phrases.GetTitlePhrase("forums")
header.Zone = "forums" header.Zone = "forums"
header.Path = "/forums/" header.Path = "/forums/"