storm
storm copied to clipboard
Performance improvement suggestions
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:
- instead of dealin with plain json data, compress response servers-side and uncompress client-side. Those data is highly compressible.
- ~~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~~
- 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)
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
}