Skip to content

Commit

Permalink
Use chunked transfer encoding (default for go 1.15)
Browse files Browse the repository at this point in the history
Since the event-stream is using a chunked transfer-encoding, we
have to calculate the size of the data so that client knows how big the
chunk was

format for every chunked event:
size(in hex)\r\n
data\r\n

data itself has to be a sever-sent event following the spec
(https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events)

Whent the stream is done, before closing the connection, we have to end
the chunk stream by sending the following data:

0\r\n
\r\n

Sending a 0 length data with along with an empty line will end the
keep-alive event-stream connection.

[rfc2616 3.6.1](https://tools.ietf.org/html/rfc2616#section-3.6.1)

Context: We have to hijack the connection so that bbs can be shutdown in
the case of blocked write (slow consumer). If the connection is not in
the hijacked state, ifrit can't terminate the process until the process
get io. [Previous
story](https://www.pivotaltracker.com/n/projects/1003146/stories/146272021).

Refers cloudfoundry/diego-release#552
  • Loading branch information
Amin Jamali committed Dec 3, 2020
1 parent a00611d commit 4070ad0
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions handlers/events_handlers.go
@@ -1,6 +1,8 @@
package handlers

import (
"bytes"
"fmt"
"net/http"

"code.cloudfoundry.org/bbs/events"
Expand Down Expand Up @@ -53,7 +55,6 @@ func streamEventsToResponse(logger lager.Logger, w http.ResponseWriter, eventCha
w.Header().Add("Content-Type", "text/event-stream; charset=utf-8")
w.Header().Add("Cache-Control", "no-cache, no-store, must-revalidate")
w.Header().Add("Connection", "keep-alive")
w.Header().Set("Transfer-Encoding", "identity")

w.WriteHeader(http.StatusOK)

Expand All @@ -63,6 +64,7 @@ func streamEventsToResponse(logger lager.Logger, w http.ResponseWriter, eventCha
}

defer func() {
fmt.Fprintf(conn, "0\r\n\r\n")
err := conn.Close()
if err != nil {
logger.Error("failed-to-close-connection", err)
Expand Down Expand Up @@ -95,12 +97,17 @@ func streamEventsToResponse(logger lager.Logger, w http.ResponseWriter, eventCha
return
}

err = sseEvent.Write(conn)
buf := new(bytes.Buffer)

err = sseEvent.Write(buf)
if err != nil {
logger.Error("failed-to-write-event", err)
return
}

fmt.Fprintf(conn, "%x;\r\n", buf.Len())
fmt.Fprintf(conn, "%s\r\n", buf.String())

eventID++
}
}
Expand Down

0 comments on commit 4070ad0

Please sign in to comment.