[ARVADOS] created: b750d9042e7e3fa14e7c98c9263cf13e04782a83
Git user
git at public.curoverse.com
Thu Apr 28 15:26:49 EDT 2016
at b750d9042e7e3fa14e7c98c9263cf13e04782a83 (commit)
commit b750d9042e7e3fa14e7c98c9263cf13e04782a83
Author: Tom Clegg <tom at curoverse.com>
Date: Thu Apr 28 15:26:29 2016 -0400
9068: Drop PUT requests if the client disconnects before we get a buffer.
diff --git a/services/keepstore/handlers.go b/services/keepstore/handlers.go
index 043ab69..0b675e3 100644
--- a/services/keepstore/handlers.go
+++ b/services/keepstore/handlers.go
@@ -93,6 +93,36 @@ func GetBlockHandler(resp http.ResponseWriter, req *http.Request) {
resp.Write(block)
}
+var errClientDisconnected = fmt.Errorf("client disconnected")
+
+// Get a buffer from the pool -- but give up and return a non-nil
+// error if resp implements http.CloseNotifier and tells us that the
+// client has disconnected before we get a buffer.
+func getBufferForResponseWriter(resp http.ResponseWriter, bufSize int) ([]byte, error) {
+ var closeNotifier <-chan bool
+ if resp, ok := resp.(http.CloseNotifier); ok {
+ closeNotifier = resp.CloseNotify()
+ }
+ var buf []byte
+ bufReady := make(chan []byte)
+ go func() {
+ bufReady <- bufs.Get(bufSize)
+ close(bufReady)
+ }()
+ select {
+ case buf = <-bufReady:
+ return buf, nil
+ case <-closeNotifier:
+ go func() {
+ // Even if closeNotifier happened first, we
+ // need to keep waiting for our buf so we can
+ // return it to the pool.
+ bufs.Put(<-bufReady)
+ }()
+ return nil, errClientDisconnected
+ }
+}
+
// PutBlockHandler is a HandleFunc to address Put block requests.
func PutBlockHandler(resp http.ResponseWriter, req *http.Request) {
hash := mux.Vars(req)["hash"]
@@ -116,8 +146,14 @@ func PutBlockHandler(resp http.ResponseWriter, req *http.Request) {
return
}
- buf := bufs.Get(int(req.ContentLength))
- _, err := io.ReadFull(req.Body, buf)
+ buf, err := getBufferForResponseWriter(resp, int(req.ContentLength))
+ if err != nil {
+ resp.WriteHeader(http.StatusServiceUnavailable)
+ io.WriteString(resp, err.Error())
+ return
+ }
+
+ _, err = io.ReadFull(req.Body, buf)
if err != nil {
http.Error(resp, err.Error(), 500)
bufs.Put(buf)
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list