optimise alerts with sync pool

This commit is contained in:
Azareal 2020-04-21 09:59:23 +10:00
parent ad4763a883
commit 244b75c5fe
1 changed files with 17 additions and 9 deletions

View File

@ -16,6 +16,7 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"unicode" "unicode"
@ -30,6 +31,7 @@ var successJSONBytes = []byte(`{"success":1}`)
// TODO: Refactor this // TODO: Refactor this
// TODO: Use the phrase system // TODO: Use the phrase system
var phraseLoginAlerts = []byte(`{"msgs":[{"msg":"Login to see your alerts","path":"/accounts/login"}],"count":0}`) var phraseLoginAlerts = []byte(`{"msgs":[{"msg":"Login to see your alerts","path":"/accounts/login"}],"count":0}`)
var alertStrPool = sync.Pool{}
// TODO: Refactor this endpoint // TODO: Refactor this endpoint
// TODO: Move this into the routes package // TODO: Move this into the routes package
@ -73,8 +75,7 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError
case "alerts": // A feed of events tailored for a specific user case "alerts": // A feed of events tailored for a specific user
if !user.Loggedin { if !user.Loggedin {
h := w.Header() h := w.Header()
gzw, ok := w.(c.GzipResponseWriter) if gzw, ok := w.(c.GzipResponseWriter); ok {
if ok {
w = gzw.ResponseWriter w = gzw.ResponseWriter
h.Del("Content-Encoding") h.Del("Content-Encoding")
} }
@ -100,8 +101,7 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError
} }
if count == 0 { if count == 0 {
gzw, ok := w.(c.GzipResponseWriter) if gzw, ok := w.(c.GzipResponseWriter); ok {
if ok {
w = gzw.ResponseWriter w = gzw.ResponseWriter
w.Header().Del("Content-Encoding") w.Header().Del("Content-Encoding")
} }
@ -148,8 +148,7 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError
} }
if len(alerts) == 0 || (rCreatedAt != 0 && rCreatedAt >= topCreatedAt && count == rCount) { if len(alerts) == 0 || (rCreatedAt != 0 && rCreatedAt >= topCreatedAt && count == rCount) {
gzw, ok := w.(c.GzipResponseWriter) if gzw, ok := w.(c.GzipResponseWriter); ok {
if ok {
w = gzw.ResponseWriter w = gzw.ResponseWriter
w.Header().Del("Content-Encoding") w.Header().Del("Content-Encoding")
} }
@ -164,10 +163,18 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError
return c.InternalErrorJS(err, w, r) return c.InternalErrorJS(err, w, r)
} }
var ok bool var sb *strings.Builder
var sb strings.Builder ii := alertStrPool.Get()
if ii == nil {
sb = &strings.Builder{}
} else {
sb = ii.(*strings.Builder)
sb.Reset()
}
sb.Grow(c.AlertsGrowHint + (len(alerts) * (c.AlertsGrowHint2 + 1)) - 1) sb.Grow(c.AlertsGrowHint + (len(alerts) * (c.AlertsGrowHint2 + 1)) - 1)
sb.WriteString(`{"msgs":[`) sb.WriteString(`{"msgs":[`)
var ok bool
for i, alert := range alerts { for i, alert := range alerts {
if i != 0 { if i != 0 {
sb.WriteRune(',') sb.WriteRune(',')
@ -176,7 +183,7 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError
if !ok { if !ok {
return c.InternalErrorJS(errors.New("No such actor"), w, r) return c.InternalErrorJS(errors.New("No such actor"), w, r)
} }
err := c.BuildAlertSb(&sb, alert, user) err := c.BuildAlertSb(sb, alert, user)
if err != nil { if err != nil {
return c.LocalErrorJS(err.Error(), w, r) return c.LocalErrorJS(err.Error(), w, r)
} }
@ -189,6 +196,7 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError
sb.WriteRune('}') sb.WriteRune('}')
_, _ = io.WriteString(w, sb.String()) _, _ = io.WriteString(w, sb.String())
alertStrPool.Put(sb)
default: default:
return c.PreErrorJS("Invalid Module", w, r) return c.PreErrorJS("Invalid Module", w, r)
} }