reverse proxy buffer pool

This commit is contained in:
Cadey Ratio 2017-04-28 23:22:00 -07:00
parent 27033e5fcf
commit e288c7c08c
6 changed files with 154 additions and 0 deletions

View File

@ -12,6 +12,7 @@ import (
"git.xeserv.us/xena/route/lib/tun2" "git.xeserv.us/xena/route/lib/tun2"
proto "git.xeserv.us/xena/route/proto" proto "git.xeserv.us/xena/route/proto"
"github.com/mtneug/pkg/ulid" "github.com/mtneug/pkg/ulid"
"github.com/oxtoacart/bpool"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@ -139,6 +140,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Director: s.Director, Director: s.Director,
Transport: s.ts, Transport: s.ts,
FlushInterval: 1 * time.Second, FlushInterval: 1 * time.Second,
BufferPool: bpool.NewBytePool(256, 4096),
} }
rp.ServeHTTP(w, r) rp.ServeHTTP(w, r)

View File

@ -133,3 +133,4 @@ da118f7b8e5954f39d0d2130ab35d4bf0e3cb344 golang.org/x/net/context
0eb507a2ca07f13baf499f89d66cc566bf644643 (dirty) google.golang.org/grpc/credentials 0eb507a2ca07f13baf499f89d66cc566bf644643 (dirty) google.golang.org/grpc/credentials
737072b4e32b7a5018b4a7125da8d12de90e8045 github.com/mattn/go-runewidth 737072b4e32b7a5018b4a7125da8d12de90e8045 github.com/mattn/go-runewidth
44e365d423f4f06769182abfeeae2b91be9d529b github.com/olekukonko/tablewriter 44e365d423f4f06769182abfeeae2b91be9d529b github.com/olekukonko/tablewriter
4e1c5567d7c2dd59fa4c7c83d34c2f3528b025d6 github.com/oxtoacart/bpool

6
vendor/github.com/oxtoacart/bpool/bpool.go generated vendored Normal file
View File

@ -0,0 +1,6 @@
/*
Package bpool implements leaky pools of byte arrays and Buffers as bounded
channels. It is based on the leaky buffer example from the Effective Go
documentation: http://golang.org/doc/effective_go.html#leaky_buffer
*/
package bpool

40
vendor/github.com/oxtoacart/bpool/bufferpool.go generated vendored Normal file
View File

@ -0,0 +1,40 @@
package bpool
import (
"bytes"
)
// BufferPool implements a pool of bytes.Buffers in the form of a bounded
// channel.
type BufferPool struct {
c chan *bytes.Buffer
}
// NewBufferPool creates a new BufferPool bounded to the given size.
func NewBufferPool(size int) (bp *BufferPool) {
return &BufferPool{
c: make(chan *bytes.Buffer, size),
}
}
// Get gets a Buffer from the BufferPool, or creates a new one if none are
// available in the pool.
func (bp *BufferPool) Get() (b *bytes.Buffer) {
select {
case b = <-bp.c:
// reuse existing buffer
default:
// create new buffer
b = bytes.NewBuffer([]byte{})
}
return
}
// Put returns the given Buffer to the BufferPool.
func (bp *BufferPool) Put(b *bytes.Buffer) {
b.Reset()
select {
case bp.c <- b:
default: // Discard the buffer if the pool is full.
}
}

45
vendor/github.com/oxtoacart/bpool/bytepool.go generated vendored Normal file
View File

@ -0,0 +1,45 @@
package bpool
// BytePool implements a leaky pool of []byte in the form of a bounded
// channel.
type BytePool struct {
c chan []byte
w int
}
// NewBytePool creates a new BytePool bounded to the given maxSize, with new
// byte arrays sized based on width.
func NewBytePool(maxSize int, width int) (bp *BytePool) {
return &BytePool{
c: make(chan []byte, maxSize),
w: width,
}
}
// Get gets a []byte from the BytePool, or creates a new one if none are
// available in the pool.
func (bp *BytePool) Get() (b []byte) {
select {
case b = <-bp.c:
// reuse existing buffer
default:
// create new buffer
b = make([]byte, bp.w)
}
return
}
// Put returns the given Buffer to the BytePool.
func (bp *BytePool) Put(b []byte) {
select {
case bp.c <- b:
// buffer went back into pool
default:
// buffer didn't go back into pool, just discard
}
}
// Width returns the width of the byte arrays in this pool.
func (bp *BytePool) Width() (n int) {
return bp.w
}

60
vendor/github.com/oxtoacart/bpool/sizedbufferpool.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
package bpool
import (
"bytes"
)
// 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
}
// SizedBufferPool 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.
}
}