From 77b94a8b61310b4428a365da5a8279db72f23374 Mon Sep 17 00:00:00 2001 From: Dan Hirsch Date: Sun, 27 Oct 2013 21:17:10 -0400 Subject: [PATCH 1/2] Make /events API send headers immediately Go's net/http API does not send headers until the first call to ResponseWriter.Write(). Ordinarily, this is fine, because in most cases, responses are returned immediately. However, for the events API, nothing is written until some event is sent, which causes timeouts and/or hangs in some HTTP client APIs, which wait for headers before returning from the "make request" call. Upstream-commit: dd9f4524d1a829a394f5d96da0c1e6338c476019 Component: engine --- components/engine/api.go | 1 + 1 file changed, 1 insertion(+) diff --git a/components/engine/api.go b/components/engine/api.go index 6c1c47a001..517fe59923 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -236,6 +236,7 @@ func getEvents(srv *Server, version float64, w http.ResponseWriter, r *http.Requ } w.Header().Set("Content-Type", "application/json") wf := utils.NewWriteFlusher(w) + wf.Write([]byte{}) if since != 0 { // If since, send previous events that happened after the timestamp for _, event := range srv.events { From ee347d7b680dbd206cff833d32ceff8646bd20f9 Mon Sep 17 00:00:00 2001 From: Dan Hirsch Date: Fri, 1 Nov 2013 13:11:21 -0400 Subject: [PATCH 2/2] Added explicit Flush method to utils.WriteFlusher Upstream-commit: a963ff5d8df4e6d0e42dd669d3d60aafb8f880a7 Component: engine --- components/engine/api.go | 10 +++++----- components/engine/utils/utils.go | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/components/engine/api.go b/components/engine/api.go index 517fe59923..44e83349ca 100644 --- a/components/engine/api.go +++ b/components/engine/api.go @@ -72,12 +72,12 @@ func httpError(w http.ResponseWriter, err error) { statusCode = http.StatusUnauthorized } else if strings.Contains(err.Error(), "hasn't been activated") { statusCode = http.StatusForbidden - } - + } + if err != nil { utils.Errorf("HTTP Error: statusCode=%d %s", statusCode, err.Error()) - http.Error(w, err.Error(), statusCode) - } + http.Error(w, err.Error(), statusCode) + } } func writeJSON(w http.ResponseWriter, code int, v interface{}) error { @@ -236,7 +236,7 @@ func getEvents(srv *Server, version float64, w http.ResponseWriter, r *http.Requ } w.Header().Set("Content-Type", "application/json") wf := utils.NewWriteFlusher(w) - wf.Write([]byte{}) + wf.Flush() if since != 0 { // If since, send previous events that happened after the timestamp for _, event := range srv.events { diff --git a/components/engine/utils/utils.go b/components/engine/utils/utils.go index 389203b985..a90f4e9f06 100644 --- a/components/engine/utils/utils.go +++ b/components/engine/utils/utils.go @@ -616,6 +616,13 @@ func (wf *WriteFlusher) Write(b []byte) (n int, err error) { return n, err } +// Flush the stream immediately. +func (wf *WriteFlusher) Flush() { + wf.Lock() + defer wf.Unlock() + wf.flusher.Flush() +} + func NewWriteFlusher(w io.Writer) *WriteFlusher { var flusher http.Flusher if f, ok := w.(http.Flusher); ok {