diff --git a/common/extend.go b/common/extend.go index b3d76fc5..56987dbf 100644 --- a/common/extend.go +++ b/common/extend.go @@ -84,6 +84,7 @@ var hookTable = &HookTable{ "forum_check_pre_perms": nil, "route_topic_list_start": nil, + "route_forum_list_start": nil, "action_end_create_topic": nil, "action_end_edit_topic":nil, diff --git a/common/routes_common.go b/common/routes_common.go index 61b56b40..eab841f4 100644 --- a/common/routes_common.go +++ b/common/routes_common.go @@ -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 // ? - 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() - } + //} //PrepResources(user,header,theme) return header, nil diff --git a/experimental/plugin_hyperdrive.go b/experimental/plugin_hyperdrive.go index 2643ebd9..4b42bddd 100644 --- a/experimental/plugin_hyperdrive.go +++ b/experimental/plugin_hyperdrive.go @@ -26,20 +26,24 @@ 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) + plugin.AddHook("route_topic_list_start",jumpHdriveTopicList) + plugin.AddHook("route_forum_list_start",jumpHdriveForumList) 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) + plugin.RemoveHook("route_topic_list_start",jumpHdriveTopicList) + plugin.RemoveHook("route_forum_list_start",jumpHdriveForumList) hyperspace = nil } type Hyperspace struct { topicList atomic.Value gzipTopicList atomic.Value + forumList atomic.Value + gzipForumList atomic.Value lastTopicListUpdate atomic.Value } @@ -47,6 +51,8 @@ func newHyperspace() *Hyperspace { pageCache := new(Hyperspace) pageCache.topicList.Store([]byte("")) pageCache.gzipTopicList.Store([]byte("")) + pageCache.forumList.Store([]byte("")) + pageCache.gzipForumList.Store([]byte("")) pageCache.lastTopicListUpdate.Store(int64(0)) return pageCache } @@ -63,6 +69,8 @@ func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) { // Avoid accidentally caching already cached content hyperspace.topicList.Store([]byte("")) hyperspace.gzipTopicList.Store([]byte("")) + hyperspace.forumList.Store([]byte("")) + hyperspace.gzipForumList.Store([]byte("")) w := httptest.NewRecorder() req := httptest.NewRequest("get", "/topics/", bytes.NewReader(nil)) @@ -92,25 +100,62 @@ func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) { return false, nil } 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()) 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 w := args[0].(http.ResponseWriter) var iw http.ResponseWriter gzw, ok := w.(c.GzipResponseWriter) if ok { - tList = hyperspace.gzipTopicList.Load().([]byte) + tList = pg iw = gzw.ResponseWriter } else { - tList = hyperspace.topicList.Load().([]byte) + tList = p iw = w } if len(tList) == 0 { - c.DebugLog("no topiclist in hyperspace") + c.DebugLog("no itemlist in hyperspace") return false, nil } //c.DebugLog("tList: ", tList) diff --git a/routes/forum_list.go b/routes/forum_list.go index 8d9c0d84..d607af7a 100644 --- a/routes/forum_list.go +++ b/routes/forum_list.go @@ -9,6 +9,11 @@ import ( ) 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.Zone = "forums" header.Path = "/forums/"