add actionSuccess function to reduce boilerplate

skip doPush if there is nothing to push
optimise cdnpush string building
use string builder for server push strings
This commit is contained in:
Azareal 2020-05-27 14:15:02 +10:00
parent 4eaf0c472a
commit 77669d42a5
5 changed files with 72 additions and 74 deletions

View File

@ -24,52 +24,64 @@ func ParseSEOURL(urlBit string) (slug string, id int, err error) {
return halves[0], tid, err return halves[0], tid, err
} }
const slen1 = len("</s/>;rel=preload;as=script,") const slen1 = len("</s/>;rel=preload;as=script,") + 6
const slen2 = len("</s/>;rel=preload;as=style,") const slen2 = len("</s/>;rel=preload;as=style,") + 7
var pushCdnPool = sync.Pool{} var pushStrPool = sync.Pool{}
func doPush(w http.ResponseWriter, header *c.Header) { func doPush(w http.ResponseWriter, h *c.Header) {
//fmt.Println("in doPush") //fmt.Println("in doPush")
if len(h.Scripts) == 0 && len(h.ScriptsAsync) == 0 && len(h.Stylesheets) == 0 {
return
}
if c.Config.EnableCDNPush { if c.Config.EnableCDNPush {
var sb *strings.Builder var sb *strings.Builder = &strings.Builder{}
ii := pushCdnPool.Get() /*ii := pushStrPool.Get()
if ii == nil { if ii == nil {
sb = &strings.Builder{} sb = &strings.Builder{}
} else { } else {
sb = ii.(*strings.Builder) sb = ii.(*strings.Builder)
sb.Reset() sb.Reset()
} }*/
sb.Grow((slen1 * (len(h.Scripts) + len(h.ScriptsAsync))) + ((slen2 + 7) * len(h.Stylesheets)))
push := func(in []string) { push := func(in []string) {
sb.Grow((slen1 + 6) * len(in)) for i, path := range in {
for _, path := range in { if i != 0 {
sb.WriteString(",</s/")
} else {
sb.WriteString("</s/") sb.WriteString("</s/")
}
sb.WriteString(path) sb.WriteString(path)
sb.WriteString(">;rel=preload;as=script,") sb.WriteString(">;rel=preload;as=script")
} }
} }
push(header.Scripts) push(h.Scripts)
//push(header.PreScriptsAsync) //push(h.PreScriptsAsync)
push(header.ScriptsAsync) push(h.ScriptsAsync)
if len(header.Stylesheets) > 0 { if len(h.Stylesheets) > 0 {
sb.Grow((slen2 + 7) * len(header.Stylesheets)) for i, path := range h.Stylesheets {
for _, path := range header.Stylesheets { if i != 0 {
sb.WriteString(",</s/")
} else {
sb.WriteString("</s/") sb.WriteString("</s/")
}
sb.WriteString(path) sb.WriteString(path)
sb.WriteString(">;rel=preload;as=style,") sb.WriteString(">;rel=preload;as=style")
} }
} }
// TODO: Push avatars? // TODO: Push avatars?
if sb.Len() > 0 { if sb.Len() > 0 {
sbuf := sb.String() sbuf := sb.String()
pushCdnPool.Put(sb) w.Header().Set("Link", sbuf)
w.Header().Set("Link", sbuf[:len(sbuf)-1]) //pushStrPool.Put(sb)
} }
} else if !c.Config.DisableServerPush { } else if !c.Config.DisableServerPush {
//fmt.Println("push enabled") //fmt.Println("push enabled")
if gzw, ok := w.(c.GzipResponseWriter); ok { /*if bzw, ok := w.(c.BrResponseWriter); ok {
w = bzw.ResponseWriter
} else */if gzw, ok := w.(c.GzipResponseWriter); ok {
w = gzw.ResponseWriter w = gzw.ResponseWriter
} }
pusher, ok := w.(http.Pusher) pusher, ok := w.(http.Pusher)
@ -79,21 +91,33 @@ func doPush(w http.ResponseWriter, header *c.Header) {
//panic("has pusher") //panic("has pusher")
//fmt.Println("has pusher") //fmt.Println("has pusher")
var sb *strings.Builder = &strings.Builder{}
/*ii := pushStrPool.Get()
if ii == nil {
sb = &strings.Builder{}
} else {
sb = ii.(*strings.Builder)
sb.Reset()
}*/
sb.Grow(6 * (len(h.Scripts) + len(h.ScriptsAsync) + len(h.Stylesheets)))
push := func(in []string) { push := func(in []string) {
for _, path := range in { for _, path := range in {
//fmt.Println("pushing /s/" + path) //fmt.Println("pushing /s/" + path)
// TODO: Avoid concatenating here sb.WriteString("/s/")
err := pusher.Push("/s/"+path, nil) sb.WriteString(path)
err := pusher.Push(sb.String(), nil)
if err != nil { if err != nil {
break break
} }
sb.Reset()
} }
} }
push(header.Scripts) push(h.Scripts)
//push(header.PreScriptsAsync) //push(h.PreScriptsAsync)
push(header.ScriptsAsync) push(h.ScriptsAsync)
push(header.Stylesheets) push(h.Stylesheets)
// TODO: Push avatars? // TODO: Push avatars?
//pushStrPool.Put(sb)
} }
} }
@ -172,8 +196,21 @@ func renderTemplate3(tmplName, hookName string, w http.ResponseWriter, r *http.R
if c.RunPreRenderHook("pre_render_"+hookName, w, r, h.CurrentUser, pi) { if c.RunPreRenderHook("pre_render_"+hookName, w, r, h.CurrentUser, pi) {
return nil return nil
} }
/*defer func() {
c.StrSlicePool.Put(h.Scripts)
c.StrSlicePool.Put(h.PreScriptsAsync)
}()*/
return h.Theme.RunTmpl(tmplName, pi, w) return h.Theme.RunTmpl(tmplName, pi, w)
} }
// TODO: Rename renderTemplate to RenderTemplate instead of using this hack to avoid breaking things // TODO: Rename renderTemplate to RenderTemplate instead of using this hack to avoid breaking things
var RenderTemplate = renderTemplate3 var RenderTemplate = renderTemplate3
func actionSuccess(w http.ResponseWriter, r *http.Request, dest string, js bool) c.RouteError {
if !js {
http.Redirect(w, r, dest, http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
}

View File

@ -131,11 +131,5 @@ func ChangeTheme(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)} cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}
http.SetCookie(w, &cookie) http.SetCookie(w, &cookie)
return actionSuccess(w, r, "/", js)
if !js {
http.Redirect(w, r, "/", http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
} }

View File

@ -513,13 +513,7 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid str
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
return actionSuccess(w, r, "/topic/"+strconv.Itoa(reply.ParentID), js)
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
} }
func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError { func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError {
@ -558,7 +552,6 @@ func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid s
} else if err != nil { } else if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
err = reply.Unlike(u.ID) err = reply.Unlike(u.ID)
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
@ -581,11 +574,5 @@ func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid s
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
return actionSuccess(w, r, "/topic/"+strconv.Itoa(reply.ParentID), js)
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(reply.ParentID), http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
} }

View File

@ -103,12 +103,6 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sItemID
return c.LocalError("Someone has already reported this!", w, r, user) return c.LocalError("Someone has already reported this!", w, r, user)
} }
counters.PostCounter.Bump() counters.PostCounter.Bump()
if !js {
// TODO: Redirect back to where we came from // TODO: Redirect back to where we came from
http.Redirect(w, r, "/", http.StatusSeeOther) return actionSuccess(w, r, "/", js)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
} }

View File

@ -979,13 +979,7 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
return actionSuccess(w, r, "/topic/"+strconv.Itoa(tid), js)
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
} }
func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError { func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
@ -993,7 +987,6 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sti
if err != nil { if err != nil {
return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js) return c.PreErrorJSQ(phrases.GetErrorPhrase("id_must_be_integer"), w, r, js)
} }
topic, err := c.Topics.Get(tid) topic, err := c.Topics.Get(tid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, js) return c.PreErrorJSQ("The requested topic doesn't exist.", w, r, js)
@ -1016,7 +1009,6 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sti
} else if err != nil { } else if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
err = topic.Unlike(user.ID) err = topic.Unlike(user.ID)
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
@ -1039,11 +1031,5 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sti
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
return actionSuccess(w, r, "/topic/"+strconv.Itoa(tid), js)
if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
} else {
_, _ = w.Write(successJSONBytes)
}
return nil
} }