From e09d5690a74ab43afacfc5fc555365c1c4d23355 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Thu, 30 Mar 2023 23:40:36 +0530 Subject: [PATCH] Optimize JSON marshalling in playbooks (#22735) While inspecting Pyroscope, the function api.ReturnJSON was seen to take some chunk of the overall memory allocations. Looking deeper, we can see that the entire object is json marshalled into bytes, and then wrote to the network. Instead, we can just do a streaming write to the network which avoids pre-allocating the entire object. A similar approach is taken in the server channels codebase as well. ```release-note NONE ``` --- server/playbooks/server/api/api.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/server/playbooks/server/api/api.go b/server/playbooks/server/api/api.go index 24b775f948..7c348c21dc 100644 --- a/server/playbooks/server/api/api.go +++ b/server/playbooks/server/api/api.go @@ -91,16 +91,10 @@ func HandleErrorWithCode(logger logrus.FieldLogger, w http.ResponseWriter, code // ReturnJSON writes the given pointerToObject as json with the provided httpStatus func ReturnJSON(w http.ResponseWriter, pointerToObject interface{}, httpStatus int) { - jsonBytes, err := json.Marshal(pointerToObject) - if err != nil { - logrus.WithError(err).Error("Unable to marshal JSON") - return - } - w.Header().Set("Content-Type", "application/json") w.WriteHeader(httpStatus) - if _, err = w.Write(jsonBytes); err != nil { + if err := json.NewEncoder(w).Encode(pointerToObject); err != nil { logrus.WithError(err).Warn("Unable to write to http.ResponseWriter") return }