From e3e5d62e940cb425438c8d8888bd5522ac1e0860 Mon Sep 17 00:00:00 2001 From: Azareal Date: Sat, 20 Apr 2019 22:49:48 +1000 Subject: [PATCH] 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. --- common/extend.go | 1 + common/widget_wol.go | 47 +++++++++++++++++++++++++++++-- common/widgets.go | 2 +- experimental/plugin_hyperdrive.go | 22 ++++++++++----- 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/common/extend.go b/common/extend.go index c9855cfe..b3d76fc5 100644 --- a/common/extend.go +++ b/common/extend.go @@ -111,6 +111,7 @@ var hookTable = &HookTable{ "router_pre_route": nil, "tasks_tick_topic_list": nil, + "tasks_tick_widget_wol": nil, }, map[string][]func(string) string{ "preparse_preassign": nil, diff --git a/common/widget_wol.go b/common/widget_wol.go index 620b8e42..a025161e 100644 --- a/common/widget_wol.go +++ b/common/widget_wol.go @@ -20,7 +20,7 @@ func wolInit(widget *Widget, schedule *WidgetScheduler) error { return nil } -func wolBuild(widget *Widget, hvars interface{}) (string, error) { +func wolGetUsers() ([]*User,int) { ucount := WsHub.UserCount() // We don't want a ridiculously long list, so we'll show the number if it's too high and only show staff individually var users []*User @@ -30,6 +30,11 @@ func wolBuild(widget *Widget, hvars interface{}) (string, error) { users = nil } } + return users, ucount +} + +func wolBuild(widget *Widget, hvars interface{}) (string, error) { + users, ucount := wolGetUsers() wol := &wolUsers{hvars.(*Header), phrases.GetTmplPhrase("widget.online_name"), users, ucount} err := wol.Header.Theme.RunTmpl("widget_online", wol, wol.Header.Writer) return "", err @@ -46,18 +51,54 @@ func wolRender(widget *Widget, hvars interface{}) (string, error) { return wolBuild(widget, hvars) } +var wolLastUsers []*User + func wolTick(widget *Widget) error { w := httptest.NewRecorder() - _, err := wolBuild(widget, SimpleDefaultHeader(w)) + users, ucount := wolGetUsers() + //log.Printf("users: %+v\n",users) + //log.Printf("wolLastUsers: %+v\n",wolLastUsers) + + // Avoid rebuilding the widget, if the users are exactly the same as on the last tick + if len(users) == len(wolLastUsers) { + diff := false + for i, user := range users { + if user.ID != wolLastUsers[i].ID { + diff = true + } + } + if !diff { + iTickMask := widget.TickMask.Load() + if iTickMask != nil { + tickMask := iTickMask.(*Widget) + if tickMask != nil { + return nil + } + } + } + } + + wol := &wolUsers{SimpleDefaultHeader(w), phrases.GetTmplPhrase("widget.online_name"), users, ucount} + err := wol.Header.Theme.RunTmpl("widget_online", wol, wol.Header.Writer) if err != nil { return err } + buf := new(bytes.Buffer) buf.ReadFrom(w.Result().Body) bs := buf.String() if Config.MinifyTemplates { bs = min.Minify(bs) } - widget.TickMask.Store(bs) + + twidget := &Widget{} + *twidget = *widget + twidget.Body = bs + widget.TickMask.Store(twidget) + wolLastUsers = users + + hTbl := GetHookTable() + _, _ = hTbl.VhookSkippable("tasks_tick_widget_wol", widget, bs) + return nil } diff --git a/common/widgets.go b/common/widgets.go index 8b1ab40c..fa9314bc 100644 --- a/common/widgets.go +++ b/common/widgets.go @@ -349,7 +349,7 @@ func (schedule *WidgetScheduler) Tick() error { if widget.TickFunc == nil { continue } - err := widget.TickFunc(widget.Copy()) + err := widget.TickFunc(widget) if err != nil { return err } diff --git a/experimental/plugin_hyperdrive.go b/experimental/plugin_hyperdrive.go index eb770f87..fd767d87 100644 --- a/experimental/plugin_hyperdrive.go +++ b/experimental/plugin_hyperdrive.go @@ -2,7 +2,7 @@ package main import ( - "log" + //"log" "bytes" "sync/atomic" "net/http" @@ -21,12 +21,14 @@ func init() { 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 } @@ -41,9 +43,14 @@ func newHyperspace() *Hyperspace { 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) { - log.Print("Refueling...") + c.DebugLog("Refueling...") w := httptest.NewRecorder() req := httptest.NewRequest("get", "/topics/", bytes.NewReader(nil)) user := c.GuestUser @@ -73,25 +80,26 @@ func tickHdrive(args ...interface{}) (skip bool, rerr c.RouteError) { func jumpHdrive(args ...interface{}) (skip bool, rerr c.RouteError) { tList := hyperspace.topicList.Load().([]byte) if len(tList) == 0 { - log.Print("no topiclist in hyperspace") + 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 { - log.Print("not guest") + 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) - //log.Print("r.URL.Path:",r.URL.Path) - log.Print("r.URL.RawQuery:",r.URL.RawQuery) + //c.DebugLog("r.URL.Path:",r.URL.Path) + //c.DebugLog("r.URL.RawQuery:",r.URL.RawQuery) if r.URL.RawQuery != "" { return false, nil } - log.Print("Successful jump") + //c.DebugLog + c.DebugLog("Successful jump") w := args[0].(http.ResponseWriter) header := args[3].(*c.Header)