From da480e8529690d7a2c23f13ab4873bf8a4acaaba Mon Sep 17 00:00:00 2001 From: Percy Wegmann Date: Thu, 21 Mar 2024 06:34:19 -0500 Subject: [PATCH] ipn/localapi: reuse buffer for encoding JSON in serveWatchIPNBus Reuse a single byte buffer for JSON encoding all notifications to the same subscriber. This retains more memory, but produces less garbage. Updates tailscale/corp#18514 Signed-off-by: Percy Wegmann --- ipn/localapi/localapi.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go index f6db3d4a4..603c61304 100644 --- a/ipn/localapi/localapi.go +++ b/ipn/localapi/localapi.go @@ -1289,14 +1289,16 @@ func (h *Handler) serveWatchIPNBus(w http.ResponseWriter, r *http.Request) { } w.Header().Set("Content-Type", "application/json") + buf := bytes.NewBuffer(nil) ctx := r.Context() h.b.WatchNotifications(ctx, mask, f.Flush, func(roNotify *ipn.Notify) (keepGoing bool) { - js, err := json.Marshal(roNotify) + buf.Reset() + err := json.NewEncoder(buf).Encode(roNotify) if err != nil { h.logf("json.Marshal: %v", err) return false } - if _, err := fmt.Fprintf(w, "%s\n", js); err != nil { + if _, err := w.Write(buf.Bytes()); err != nil { return false } f.Flush()