diff --git a/go.mod b/go.mod index 5b10ac58c..f03ca60d9 100644 --- a/go.mod +++ b/go.mod @@ -122,7 +122,7 @@ require ( github.com/unknwon/com v1.0.1 github.com/unknwon/i18n v0.0.0-20200823051745-09abd91c7f2c 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/willf/bitset v1.1.11 // indirect github.com/xanzy/go-gitlab v0.44.0 diff --git a/go.sum b/go.sum index ef046bedd..46200815e 100644 --- a/go.sum +++ b/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/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.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.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= diff --git a/vendor/github.com/unrolled/render/.travis.yml b/vendor/github.com/unrolled/render/.travis.yml deleted file mode 100644 index 9ec8d547f..000000000 --- a/vendor/github.com/unrolled/render/.travis.yml +++ /dev/null @@ -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 diff --git a/vendor/github.com/unrolled/render/README.md b/vendor/github.com/unrolled/render/README.md index 5ffa2a7c1..abc210ea4 100644 --- a/vendor/github.com/unrolled/render/README.md +++ b/vendor/github.com/unrolled/render/README.md @@ -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. diff --git a/vendor/github.com/unrolled/render/buffer.go b/vendor/github.com/unrolled/render/buffer.go index cdc92ffbd..804d775b7 100644 --- a/vendor/github.com/unrolled/render/buffer.go +++ b/vendor/github.com/unrolled/render/buffer.go @@ -2,9 +2,6 @@ package render 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. // Pulled from the github.com/oxtoacart/bpool package (Apache licensed). type BufferPool struct { @@ -39,8 +36,3 @@ func (bp *BufferPool) Put(b *bytes.Buffer) { default: // Discard the buffer if the pool is full. } } - -// Initialize buffer pool for writing templates into. -func init() { - bufPool = NewBufferPool(64) -} diff --git a/vendor/github.com/unrolled/render/engine.go b/vendor/github.com/unrolled/render/engine.go index cdf1a1b16..283a3772c 100644 --- a/vendor/github.com/unrolled/render/engine.go +++ b/vendor/github.com/unrolled/render/engine.go @@ -30,6 +30,8 @@ type HTML struct { Head Name string Templates *template.Template + + bp GenericBufferPool } // JSON built-in renderer. @@ -82,9 +84,14 @@ func (d Data) Render(w io.Writer, v interface{}) error { // Render a HTML response. func (h HTML) Render(w io.Writer, binding interface{}) error { - // Retrieve a buffer from the pool to write to. - out := bufPool.Get() - err := h.Templates.ExecuteTemplate(out, h.Name, binding) + var buf *bytes.Buffer + if h.bp != nil { + // 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 { return err } @@ -92,10 +99,8 @@ func (h HTML) Render(w io.Writer, binding interface{}) error { if hw, ok := w.(http.ResponseWriter); ok { h.Head.Write(hw) } - out.WriteTo(w) + buf.WriteTo(w) - // Return the buffer to the pool. - bufPool.Put(out) return nil } diff --git a/vendor/github.com/unrolled/render/genericbufferpool.go b/vendor/github.com/unrolled/render/genericbufferpool.go new file mode 100644 index 000000000..7e8d34246 --- /dev/null +++ b/vendor/github.com/unrolled/render/genericbufferpool.go @@ -0,0 +1,9 @@ +package render + +import "bytes" + +// GenericBufferPool abstracts buffer pool implementations +type GenericBufferPool interface { + Get() *bytes.Buffer + Put(*bytes.Buffer) +} diff --git a/vendor/github.com/unrolled/render/render.go b/vendor/github.com/unrolled/render/render.go index 3259f620e..4cd11cdfc 100644 --- a/vendor/github.com/unrolled/render/render.go +++ b/vendor/github.com/unrolled/render/render.go @@ -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. // ***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 + + // 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. @@ -176,6 +180,10 @@ func (r *Render) prepareOptions() { if len(r.opt.XMLContentType) == 0 { 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() { @@ -410,6 +418,7 @@ func (r *Render) HTML(w io.Writer, status int, name string, binding interface{}, Head: head, Name: name, Templates: r.templates, + bp: r.opt.BufferPool, } return r.Render(w, h, binding) diff --git a/vendor/github.com/unrolled/render/sizedbufferpool.go b/vendor/github.com/unrolled/render/sizedbufferpool.go new file mode 100644 index 000000000..901c983e3 --- /dev/null +++ b/vendor/github.com/unrolled/render/sizedbufferpool.go @@ -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. + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 137e00db1..f5ea4af54 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -777,7 +777,7 @@ github.com/unknwon/i18n # github.com/unknwon/paginater v0.0.0-20200328080006-042474bd0eae ## explicit github.com/unknwon/paginater -# github.com/unrolled/render v1.0.3 +# github.com/unrolled/render v1.1.0 ## explicit github.com/unrolled/render # github.com/urfave/cli v1.22.5