storm icon indicating copy to clipboard operation
storm copied to clipboard

Performance improvement suggestions

Open malwinmp opened this issue 2 years ago • 1 comments

Hi, I observed that some json responses can get really huge really fast. Dealing with deluge instance containing lots of items generates in my case 2MB json response sending to client every 2 secs. While it's not a big deal when using server-client locally it can be serious performance issue.

What do you think about implementing some performance improvements like:

  1. instead of dealin with plain json data, compress response servers-side and uncompress client-side. Those data is highly compressible.
  2. ~~do some basic filtering server-side - for example when use filter only for Active or Downloading or Paused items return only items matching those criteria instead of sending whole list~~
  3. reduce response size by removing unused parameters like, "Peers" / "Files" / "FileProgress" / "FilePriorities" and many more that are not used for data presentation.

Edit: point 2 removed it already works that way (filtered by deluge daemon)

malwinmp avatar Nov 10 '23 08:11 malwinmp

Never programmed in go language but this change in http.go Send function seems to work.

Before transferred : 2.03MB After transferred : 172KB

package storm

import (
	"compress/gzip"
	"encoding/json"
	"net/http"
)

// HandlerFunc is an adaptor for the http.HandlerFunc that returns JSON data.
type HandlerFunc func(r *http.Request) (interface{}, error)

// Send sends JSON data to the client using the supplied HTTP status code.
func Send(rw http.ResponseWriter, code int, data interface{}) {
	enc := json.NewEncoder(rw)
	enc.SetIndent("", "  ")

	rw.Header().Set("Content-Type", "application/json")
	rw.Header().Set("Content-Encoding", "gzip")
	rw.WriteHeader(code)

	body, err := json.Marshal(data)
	if err != nil {
		return
	}
	writer, err := gzip.NewWriterLevel(rw, gzip.BestCompression)
	if err != nil {
		return
	}
	defer writer.Close()
	writer.Write(body)
}

// NoContent sends a 204 No Content response
func NoContent(rw http.ResponseWriter) {
	rw.WriteHeader(http.StatusNoContent)
}

func Handle(rw http.ResponseWriter, r *http.Request, handler HandlerFunc) error {
	response, err := handler(r)
	if err != nil {
		SendError(rw, err)
		return err
	}

	if response == nil {
		NoContent(rw)
		return nil
	}

	Send(rw, http.StatusOK, response)
	return nil
}

malwinmp avatar Nov 11 '23 19:11 malwinmp