From 00bc83b5828ac6357fdfff904244f311359ebc17 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 7 Apr 2019 15:29:27 +0300 Subject: [PATCH 1/4] use io.CopyBuffer with explicitly allocated buffers io.Copy uses a 32KB buffer, which pprof indicates result in significant memory usage. --- relay.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/relay.go b/relay.go index 8fa10c4..ec9ca73 100644 --- a/relay.go +++ b/relay.go @@ -376,7 +376,7 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { go func() { defer r.rmLiveHop(src.ID, dst.ID) - count, err := io.Copy(s, bs) + count, err := io.CopyBuffer(s, bs, make([]byte, 4096)) if err != nil { log.Debugf("relay copy error: %s", err) // Reset both. @@ -390,7 +390,7 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { }() go func() { - count, err := io.Copy(bs, s) + count, err := io.CopyBuffer(bs, s, make([]byte, 4096)) if err != nil { log.Debugf("relay copy error: %s", err) // Reset both. From 6e790b96db31c729b965bd21dfc9de2465816c34 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 7 Apr 2019 22:31:58 +0300 Subject: [PATCH 2/4] use a sync.Pool for relay buffers --- relay.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/relay.go b/relay.go index ec9ca73..f3f5783 100644 --- a/relay.go +++ b/relay.go @@ -40,6 +40,8 @@ type Relay struct { incoming chan *Conn + bufPool sync.Pool + relays map[peer.ID]struct{} mx sync.Mutex @@ -85,6 +87,11 @@ func NewRelay(ctx context.Context, h host.Host, upgrader *tptu.Upgrader, opts .. incoming: make(chan *Conn), relays: make(map[peer.ID]struct{}), liveHops: make(map[peer.ID]map[peer.ID]int), + bufPool: sync.Pool{ + New: func() interface{} { + return make([]byte, 4096) + }, + }, } for _, opt := range opts { @@ -376,7 +383,10 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { go func() { defer r.rmLiveHop(src.ID, dst.ID) - count, err := io.CopyBuffer(s, bs, make([]byte, 4096)) + buf := r.bufPool.Get().([]byte) + defer r.bufPool.Put(buf) + + count, err := io.CopyBuffer(s, bs, buf) if err != nil { log.Debugf("relay copy error: %s", err) // Reset both. @@ -390,7 +400,10 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { }() go func() { - count, err := io.CopyBuffer(bs, s, make([]byte, 4096)) + buf := r.bufPool.Get().([]byte) + defer r.bufPool.Put(buf) + + count, err := io.CopyBuffer(bs, s, buf) if err != nil { log.Debugf("relay copy error: %s", err) // Reset both. From 1d76489dbc2d4d5783e1a9eca9b693699cede9c6 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 8 Apr 2019 10:57:15 +0300 Subject: [PATCH 3/4] use go-buffer-pool --- go.mod | 1 + relay.go | 12 ++++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 74f01c0..777ad54 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/libp2p/go-libp2p-circuit require ( github.com/gogo/protobuf v1.2.1 github.com/ipfs/go-log v0.0.1 + github.com/libp2p/go-buffer-pool v0.0.1 github.com/libp2p/go-libp2p-blankhost v0.0.1 github.com/libp2p/go-libp2p-host v0.0.1 github.com/libp2p/go-libp2p-net v0.0.1 diff --git a/relay.go b/relay.go index f3f5783..07e49e0 100644 --- a/relay.go +++ b/relay.go @@ -10,6 +10,7 @@ import ( pb "github.com/libp2p/go-libp2p-circuit/pb" logging "github.com/ipfs/go-log" + pool "github.com/libp2p/go-buffer-pool" host "github.com/libp2p/go-libp2p-host" inet "github.com/libp2p/go-libp2p-net" peer "github.com/libp2p/go-libp2p-peer" @@ -40,7 +41,7 @@ type Relay struct { incoming chan *Conn - bufPool sync.Pool + bufPool pool.BufferPool relays map[peer.ID]struct{} mx sync.Mutex @@ -87,11 +88,6 @@ func NewRelay(ctx context.Context, h host.Host, upgrader *tptu.Upgrader, opts .. incoming: make(chan *Conn), relays: make(map[peer.ID]struct{}), liveHops: make(map[peer.ID]map[peer.ID]int), - bufPool: sync.Pool{ - New: func() interface{} { - return make([]byte, 4096) - }, - }, } for _, opt := range opts { @@ -383,7 +379,7 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { go func() { defer r.rmLiveHop(src.ID, dst.ID) - buf := r.bufPool.Get().([]byte) + buf := r.bufPool.Get(4096) defer r.bufPool.Put(buf) count, err := io.CopyBuffer(s, bs, buf) @@ -400,7 +396,7 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { }() go func() { - buf := r.bufPool.Get().([]byte) + buf := r.bufPool.Get(4096) defer r.bufPool.Put(buf) count, err := io.CopyBuffer(bs, s, buf) From 94c29c0b670c4b75e8c1fb80e4d3f4fbc08adbfa Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 8 Apr 2019 10:59:44 +0300 Subject: [PATCH 4/4] use global buffer pool --- relay.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/relay.go b/relay.go index 07e49e0..ddda926 100644 --- a/relay.go +++ b/relay.go @@ -41,8 +41,6 @@ type Relay struct { incoming chan *Conn - bufPool pool.BufferPool - relays map[peer.ID]struct{} mx sync.Mutex @@ -379,8 +377,8 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { go func() { defer r.rmLiveHop(src.ID, dst.ID) - buf := r.bufPool.Get(4096) - defer r.bufPool.Put(buf) + buf := pool.Get(4096) + defer pool.Put(buf) count, err := io.CopyBuffer(s, bs, buf) if err != nil { @@ -396,8 +394,8 @@ func (r *Relay) handleHopStream(s inet.Stream, msg *pb.CircuitRelay) { }() go func() { - buf := r.bufPool.Get(4096) - defer r.bufPool.Put(buf) + buf := pool.Get(4096) + defer pool.Put(buf) count, err := io.CopyBuffer(bs, s, buf) if err != nil {