produce less garbage; reuse buffers
This commit is contained in:
parent
6ed3634876
commit
b326aa66f5
40
main.go
40
main.go
|
@ -316,32 +316,21 @@ func render(w io.Writer, rs []route) error {
|
||||||
return t.Execute(w, data)
|
return t.Execute(w, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderBytes(rs *routeStats) ([]byte, error) {
|
func compress(cw io.Writer, cr io.Reader, err error) error {
|
||||||
var buf bytes.Buffer
|
|
||||||
err := render(&buf, rs.getLongest())
|
|
||||||
return buf.Bytes(), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func compress(content []byte, err error) ([]byte, error) {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
var compressbuf bytes.Buffer
|
|
||||||
|
|
||||||
cw, err := gzip.NewWriterLevel(&compressbuf, gzip.BestCompression)
|
gzw, err := gzip.NewWriterLevel(cw, gzip.BestCompression)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = cw.Write(content); err != nil {
|
if _, err = io.Copy(gzw, cr); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = cw.Close(); err != nil {
|
return gzw.Close()
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return compressbuf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func acceptGzip(h http.Header) bool {
|
func acceptGzip(h http.Header) bool {
|
||||||
|
@ -356,8 +345,8 @@ func acceptGzip(h http.Header) bool {
|
||||||
func cachedRender(rs *routeStats) http.HandlerFunc {
|
func cachedRender(rs *routeStats) http.HandlerFunc {
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var timestamp time.Time
|
var timestamp time.Time
|
||||||
var content []byte
|
var content bytes.Buffer
|
||||||
var compressed []byte
|
var compressed bytes.Buffer
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodGet {
|
if r.Method != http.MethodGet {
|
||||||
http.Error(w, "Not Allowed", http.StatusMethodNotAllowed)
|
http.Error(w, "Not Allowed", http.StatusMethodNotAllowed)
|
||||||
|
@ -377,8 +366,11 @@ func cachedRender(rs *routeStats) http.HandlerFunc {
|
||||||
var err error
|
var err error
|
||||||
m.Lock()
|
m.Lock()
|
||||||
if time.Since(timestamp) > 5*time.Second {
|
if time.Since(timestamp) > 5*time.Second {
|
||||||
content, err = renderBytes(rs)
|
content.Reset()
|
||||||
compressed, err = compress(content, err)
|
compressed.Reset()
|
||||||
|
|
||||||
|
err = render(&content, rs.getLongest())
|
||||||
|
err = compress(&compressed, bytes.NewReader(content.Bytes()), err)
|
||||||
|
|
||||||
timestamp = time.Now()
|
timestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
@ -399,8 +391,8 @@ func cachedRender(rs *routeStats) http.HandlerFunc {
|
||||||
w.Header().Add("Content-Encoding", "gzip")
|
w.Header().Add("Content-Encoding", "gzip")
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Length", strconv.FormatInt(int64(len(c)), 10))
|
w.Header().Set("Content-Length", strconv.FormatInt(int64(c.Len()), 10))
|
||||||
http.ServeContent(w, r, "/", timestamp, bytes.NewReader(c))
|
http.ServeContent(w, r, "/", timestamp, bytes.NewReader(c.Bytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue