Skip to content
This repository has been archived by the owner on May 2, 2023. It is now read-only.

Commit

Permalink
Merge pull request #61 from brave/faster-proxy
Browse files Browse the repository at this point in the history
Make nitriding's reverse proxy faster.
  • Loading branch information
Philipp Winter committed Apr 27, 2023
2 parents e863757 + 3579234 commit 1e63964
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
39 changes: 39 additions & 0 deletions bufferpool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package nitriding

import (
"sync"
)

// bufSize represents the buffer size for our reverse proxy. It's identical to
// the buffer size used in Go's reverse proxy implementation:
// https://cs.opensource.google/go/go/+/refs/tags/go1.20.3:src/net/http/httputil/reverseproxy.go;l=634
const bufSize = 32 * 1024

// bufPool implements the httputil.BufferPool interface. The implementation is
// based on sync.Pool.
type bufPool struct {
sync.Pool
}

func newBufPool() *bufPool {
return &bufPool{
Pool: sync.Pool{
New: func() any {
// The Pool's New function should generally only return pointer
// types, since a pointer can be put into the return interface
// value without an allocation:
s := make([]byte, bufSize)
return &s
},
},
}
}

func (p *bufPool) Get() []byte {
s := p.Pool.Get()
return *s.(*[]byte)
}

func (p *bufPool) Put(buf []byte) {
p.Pool.Put(&buf)
}
14 changes: 14 additions & 0 deletions bufferpool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package nitriding

import "testing"

func TestBufPool(t *testing.T) {
p := newBufPool()
s1 := p.Get()
p.Put(s1)
s2 := p.Get()

if len(s1) != len(s2) {
t.Fatalf("Byte slices have different lengths (%d vs %d).", len(s1), len(s2))
}
}
10 changes: 9 additions & 1 deletion enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,13 @@ func NewEnclave(cfg *Config) (*Enclave, error) {
ready: make(chan bool),
}

// Increase the maximum number of idle connections per host. This is
// critical to boosting the requests per second that our reverse proxy can
// sustain. See the following comment for more details:
// https://github.com/brave/nitriding/issues/45#issuecomment-1526012586
http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 100
http.DefaultTransport.(*http.Transport).MaxIdleConns = 100

if cfg.Debug {
e.pubSrv.Handler.(*chi.Mux).Use(middleware.Logger)
e.privSrv.Handler.(*chi.Mux).Use(middleware.Logger)
Expand All @@ -209,7 +216,8 @@ func NewEnclave(cfg *Config) (*Enclave, error) {
// server.
if cfg.AppWebSrv != nil {
e.revProxy = httputil.NewSingleHostReverseProxy(cfg.AppWebSrv)
e.pubSrv.Handler.(*chi.Mux).Handle(pathProxy, proxyHandler(e))
e.revProxy.BufferPool = newBufPool()
e.pubSrv.Handler.(*chi.Mux).Handle(pathProxy, e.revProxy)
}

return e, nil
Expand Down
8 changes: 0 additions & 8 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,6 @@ func rootHandler(cfg *Config) http.HandlerFunc {
}
}

// proxyHandler returns an HTTP handler that proxies HTTP requests to the
// enclave-internal HTTP server of our enclave application.
func proxyHandler(e *Enclave) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
e.revProxy.ServeHTTP(w, r)
}
}

// reqSyncHandler returns a handler that lets the enclave application request
// state synchronization, which copies the given remote enclave's state into
// our state.
Expand Down

0 comments on commit 1e63964

Please sign in to comment.