Bump unrolled/render to v1.1.0 (#15581)
v1.1.0 has improved buffer pooling
This commit is contained in:
parent
f719ffc783
commit
445e47b692
2
go.mod
2
go.mod
|
@ -122,7 +122,7 @@ require (
|
||||||
github.com/unknwon/com v1.0.1
|
github.com/unknwon/com v1.0.1
|
||||||
github.com/unknwon/i18n v0.0.0-20210321134014-0ebbf2df1c44
|
github.com/unknwon/i18n v0.0.0-20210321134014-0ebbf2df1c44
|
||||||
github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae
|
github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae
|
||||||
github.com/unrolled/render v1.0.3
|
github.com/unrolled/render v1.1.0
|
||||||
github.com/urfave/cli v1.22.5
|
github.com/urfave/cli v1.22.5
|
||||||
github.com/willf/bitset v1.1.11 // indirect
|
github.com/willf/bitset v1.1.11 // indirect
|
||||||
github.com/xanzy/go-gitlab v0.44.0
|
github.com/xanzy/go-gitlab v0.44.0
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -1115,6 +1115,8 @@ github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae h1:ihaXiJkaca54I
|
||||||
github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae/go.mod h1:1fdkY6xxl6ExVs2QFv7R0F5IRZHKA8RahhB9fMC9RvM=
|
github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae/go.mod h1:1fdkY6xxl6ExVs2QFv7R0F5IRZHKA8RahhB9fMC9RvM=
|
||||||
github.com/unrolled/render v1.0.3 h1:baO+NG1bZSF2WR4zwh+0bMWauWky7DVrTOfvE2w+aFo=
|
github.com/unrolled/render v1.0.3 h1:baO+NG1bZSF2WR4zwh+0bMWauWky7DVrTOfvE2w+aFo=
|
||||||
github.com/unrolled/render v1.0.3/go.mod h1:gN9T0NhL4Bfbwu8ann7Ry/TGHYfosul+J0obPf6NBdM=
|
github.com/unrolled/render v1.0.3/go.mod h1:gN9T0NhL4Bfbwu8ann7Ry/TGHYfosul+J0obPf6NBdM=
|
||||||
|
github.com/unrolled/render v1.1.0 h1:gvpR9hHxTt6DcGqRYuVVFcfd8rtK+nyEPUJN06KB57Q=
|
||||||
|
github.com/unrolled/render v1.1.0/go.mod h1:gN9T0NhL4Bfbwu8ann7Ry/TGHYfosul+J0obPf6NBdM=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.11.x
|
|
||||||
- 1.12.x
|
|
||||||
- tip
|
|
||||||
|
|
||||||
env:
|
|
||||||
- GO111MODULE=on
|
|
||||||
|
|
||||||
install:
|
|
||||||
- go mod download
|
|
||||||
|
|
||||||
script:
|
|
||||||
- go test -v -race -tags=integration
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Render [![GoDoc](http://godoc.org/github.com/unrolled/render?status.svg)](http://godoc.org/github.com/unrolled/render) [![Build Status](https://travis-ci.org/unrolled/render.svg)](https://travis-ci.org/unrolled/render)
|
# Render [![GoDoc](http://godoc.org/github.com/unrolled/render?status.svg)](http://godoc.org/github.com/unrolled/render) [![Test](https://github.com/unrolled/render/workflows/Test/badge.svg?branch=v1)](https://github.com/unrolled/render/actions)
|
||||||
|
|
||||||
|
|
||||||
Render is a package that provides functionality for easily rendering JSON, XML, text, binary data, and HTML templates. This package is based on the [Martini](https://github.com/go-martini/martini) [render](https://github.com/martini-contrib/render) work.
|
Render is a package that provides functionality for easily rendering JSON, XML, text, binary data, and HTML templates. This package is based on the [Martini](https://github.com/go-martini/martini) [render](https://github.com/martini-contrib/render) work.
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,6 @@ package render
|
||||||
|
|
||||||
import "bytes"
|
import "bytes"
|
||||||
|
|
||||||
// bufPool represents a reusable buffer pool for executing templates into.
|
|
||||||
var bufPool *BufferPool
|
|
||||||
|
|
||||||
// BufferPool implements a pool of bytes.Buffers in the form of a bounded channel.
|
// BufferPool implements a pool of bytes.Buffers in the form of a bounded channel.
|
||||||
// Pulled from the github.com/oxtoacart/bpool package (Apache licensed).
|
// Pulled from the github.com/oxtoacart/bpool package (Apache licensed).
|
||||||
type BufferPool struct {
|
type BufferPool struct {
|
||||||
|
@ -39,8 +36,3 @@ func (bp *BufferPool) Put(b *bytes.Buffer) {
|
||||||
default: // Discard the buffer if the pool is full.
|
default: // Discard the buffer if the pool is full.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize buffer pool for writing templates into.
|
|
||||||
func init() {
|
|
||||||
bufPool = NewBufferPool(64)
|
|
||||||
}
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ type HTML struct {
|
||||||
Head
|
Head
|
||||||
Name string
|
Name string
|
||||||
Templates *template.Template
|
Templates *template.Template
|
||||||
|
|
||||||
|
bp GenericBufferPool
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON built-in renderer.
|
// JSON built-in renderer.
|
||||||
|
@ -82,9 +84,14 @@ func (d Data) Render(w io.Writer, v interface{}) error {
|
||||||
|
|
||||||
// Render a HTML response.
|
// Render a HTML response.
|
||||||
func (h HTML) Render(w io.Writer, binding interface{}) error {
|
func (h HTML) Render(w io.Writer, binding interface{}) error {
|
||||||
// Retrieve a buffer from the pool to write to.
|
var buf *bytes.Buffer
|
||||||
out := bufPool.Get()
|
if h.bp != nil {
|
||||||
err := h.Templates.ExecuteTemplate(out, h.Name, binding)
|
// If we have a bufferpool, allocate from it
|
||||||
|
buf = h.bp.Get()
|
||||||
|
defer h.bp.Put(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.Templates.ExecuteTemplate(buf, h.Name, binding)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -92,10 +99,8 @@ func (h HTML) Render(w io.Writer, binding interface{}) error {
|
||||||
if hw, ok := w.(http.ResponseWriter); ok {
|
if hw, ok := w.(http.ResponseWriter); ok {
|
||||||
h.Head.Write(hw)
|
h.Head.Write(hw)
|
||||||
}
|
}
|
||||||
out.WriteTo(w)
|
buf.WriteTo(w)
|
||||||
|
|
||||||
// Return the buffer to the pool.
|
|
||||||
bufPool.Put(out)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package render
|
||||||
|
|
||||||
|
import "bytes"
|
||||||
|
|
||||||
|
// GenericBufferPool abstracts buffer pool implementations
|
||||||
|
type GenericBufferPool interface {
|
||||||
|
Get() *bytes.Buffer
|
||||||
|
Put(*bytes.Buffer)
|
||||||
|
}
|
|
@ -103,6 +103,10 @@ type Options struct {
|
||||||
// Enables using partials without the current filename suffix which allows use of the same template in multiple files. e.g {{ partial "carosuel" }} inside the home template will match carosel-home or carosel.
|
// Enables using partials without the current filename suffix which allows use of the same template in multiple files. e.g {{ partial "carosuel" }} inside the home template will match carosel-home or carosel.
|
||||||
// ***NOTE*** - This option should be named RenderPartialsWithoutSuffix as that is what it does. "Prefix" is a typo. Maintaining the existing name for backwards compatibility.
|
// ***NOTE*** - This option should be named RenderPartialsWithoutSuffix as that is what it does. "Prefix" is a typo. Maintaining the existing name for backwards compatibility.
|
||||||
RenderPartialsWithoutPrefix bool
|
RenderPartialsWithoutPrefix bool
|
||||||
|
|
||||||
|
// BufferPool to use when rendering HTML templates. If none is supplied
|
||||||
|
// defaults to SizedBufferPool of size 32 with 512KiB buffers.
|
||||||
|
BufferPool GenericBufferPool
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLOptions is a struct for overriding some rendering Options for specific HTML call.
|
// HTMLOptions is a struct for overriding some rendering Options for specific HTML call.
|
||||||
|
@ -176,6 +180,10 @@ func (r *Render) prepareOptions() {
|
||||||
if len(r.opt.XMLContentType) == 0 {
|
if len(r.opt.XMLContentType) == 0 {
|
||||||
r.opt.XMLContentType = ContentXML
|
r.opt.XMLContentType = ContentXML
|
||||||
}
|
}
|
||||||
|
if r.opt.BufferPool == nil {
|
||||||
|
// 32 buffers of size 512KiB each
|
||||||
|
r.opt.BufferPool = NewSizedBufferPool(32, 1<<19)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Render) compileTemplates() {
|
func (r *Render) compileTemplates() {
|
||||||
|
@ -410,6 +418,7 @@ func (r *Render) HTML(w io.Writer, status int, name string, binding interface{},
|
||||||
Head: head,
|
Head: head,
|
||||||
Name: name,
|
Name: name,
|
||||||
Templates: r.templates,
|
Templates: r.templates,
|
||||||
|
bp: r.opt.BufferPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.Render(w, h, binding)
|
return r.Render(w, h, binding)
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Pulled from the github.com/oxtoacart/bpool package (Apache licensed).
|
||||||
|
|
||||||
|
// SizedBufferPool implements a pool of bytes.Buffers in the form of a bounded
|
||||||
|
// channel. Buffers are pre-allocated to the requested size.
|
||||||
|
type SizedBufferPool struct {
|
||||||
|
c chan *bytes.Buffer
|
||||||
|
a int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSizedBufferPool creates a new BufferPool bounded to the given size.
|
||||||
|
// size defines the number of buffers to be retained in the pool and alloc sets
|
||||||
|
// the initial capacity of new buffers to minimize calls to make().
|
||||||
|
//
|
||||||
|
// The value of alloc should seek to provide a buffer that is representative of
|
||||||
|
// most data written to the the buffer (i.e. 95th percentile) without being
|
||||||
|
// overly large (which will increase static memory consumption). You may wish to
|
||||||
|
// track the capacity of your last N buffers (i.e. using an []int) prior to
|
||||||
|
// returning them to the pool as input into calculating a suitable alloc value.
|
||||||
|
func NewSizedBufferPool(size int, alloc int) (bp *SizedBufferPool) {
|
||||||
|
return &SizedBufferPool{
|
||||||
|
c: make(chan *bytes.Buffer, size),
|
||||||
|
a: alloc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets a Buffer from the SizedBufferPool, or creates a new one if none are
|
||||||
|
// available in the pool. Buffers have a pre-allocated capacity.
|
||||||
|
func (bp *SizedBufferPool) Get() (b *bytes.Buffer) {
|
||||||
|
select {
|
||||||
|
case b = <-bp.c:
|
||||||
|
// reuse existing buffer
|
||||||
|
default:
|
||||||
|
// create new buffer
|
||||||
|
b = bytes.NewBuffer(make([]byte, 0, bp.a))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put returns the given Buffer to the SizedBufferPool.
|
||||||
|
func (bp *SizedBufferPool) Put(b *bytes.Buffer) {
|
||||||
|
b.Reset()
|
||||||
|
|
||||||
|
// Release buffers over our maximum capacity and re-create a pre-sized
|
||||||
|
// buffer to replace it.
|
||||||
|
// Note that the cap(b.Bytes()) provides the capacity from the read off-set
|
||||||
|
// only, but as we've called b.Reset() the full capacity of the underlying
|
||||||
|
// byte slice is returned.
|
||||||
|
if cap(b.Bytes()) > bp.a {
|
||||||
|
b = bytes.NewBuffer(make([]byte, 0, bp.a))
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case bp.c <- b:
|
||||||
|
default: // Discard the buffer if the pool is full.
|
||||||
|
}
|
||||||
|
}
|
|
@ -777,7 +777,7 @@ github.com/unknwon/i18n
|
||||||
# github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae
|
# github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae
|
||||||
## explicit
|
## explicit
|
||||||
github.com/unknwon/paginater
|
github.com/unknwon/paginater
|
||||||
# github.com/unrolled/render v1.0.3
|
# github.com/unrolled/render v1.1.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/unrolled/render
|
github.com/unrolled/render
|
||||||
# github.com/urfave/cli v1.22.5
|
# github.com/urfave/cli v1.22.5
|
||||||
|
|
Loading…
Reference in New Issue