From d9db3986ba8087ae2f383b515057e3e759276bcb Mon Sep 17 00:00:00 2001 From: realrasengan Date: Thu, 2 Apr 2026 21:29:51 -0700 Subject: [PATCH] reuse zlib writer to fix OOM in WASM --- transport.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/transport.go b/transport.go index 347dd74..8ba7473 100644 --- a/transport.go +++ b/transport.go @@ -63,6 +63,10 @@ type Transport struct { // Latch capability negotiation. localCaps []byte remoteCaps []byte + + // Reusable zlib writer to avoid per-tick allocations. + zlibBuf bytes.Buffer + zlibW *zlib.Writer } const ( @@ -183,7 +187,7 @@ func (t *Transport) Tick() [][]byte { // Marshal → compress → fragment → encrypt. pbData := ti.Marshal() - compressed := zlibCompress(pbData) + compressed := t.zlibCompress(pbData) frags := Fragmentize(t.sentNum, compressed) var datagrams [][]byte @@ -469,13 +473,19 @@ func (t *Transport) updateRTT(tsReply uint16) { } } -// zlibCompress compresses data with zlib (default level). -func zlibCompress(data []byte) []byte { - var buf bytes.Buffer - w := zlib.NewWriter(&buf) - w.Write(data) - w.Close() - return buf.Bytes() +// zlibCompress compresses data with zlib, reusing the writer. +func (t *Transport) zlibCompress(data []byte) []byte { + t.zlibBuf.Reset() + if t.zlibW == nil { + t.zlibW = zlib.NewWriter(&t.zlibBuf) + } else { + t.zlibW.Reset(&t.zlibBuf) + } + t.zlibW.Write(data) + t.zlibW.Close() + out := make([]byte, t.zlibBuf.Len()) + copy(out, t.zlibBuf.Bytes()) + return out } // zlibDecompress decompresses zlib data. Returns nil on error.