Avoid CompleteMultipart freeze with unexpected network issue (#15102)

If sending a white space during a long S3 handler call fails,
the whitespace goroutine forgets to return a result to the caller.
Therefore, the complete multipart handler will be blocked.

Remember to send the header written result to the caller 
or/and close the channel.
This commit is contained in:
Anis Elleuch 2022-06-17 18:41:25 +01:00 committed by GitHub
parent 5d23be6242
commit 98ddc3596c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3101,10 +3101,12 @@ func (w *whiteSpaceWriter) WriteHeader(statusCode int) {
// we do background append as and when the parts arrive and completeMultiPartUpload
// is quick. Only in a rare case where parts would be out of order will
// FS:completeMultiPartUpload() take a longer time.
func sendWhiteSpace(w http.ResponseWriter) <-chan bool {
func sendWhiteSpace(ctx context.Context, w http.ResponseWriter) <-chan bool {
doneCh := make(chan bool)
go func() {
defer close(doneCh)
ticker := time.NewTicker(time.Second * 10)
defer ticker.Stop()
headerWritten := false
for {
select {
@ -3124,7 +3126,8 @@ func sendWhiteSpace(w http.ResponseWriter) <-chan bool {
}
w.(http.Flusher).Flush()
case doneCh <- headerWritten:
ticker.Stop()
return
case <-ctx.Done():
return
}
}
@ -3298,7 +3301,7 @@ func (api objectAPIHandlers) CompleteMultipartUploadHandler(w http.ResponseWrite
}
w = &whiteSpaceWriter{ResponseWriter: w, Flusher: w.(http.Flusher)}
completeDoneCh := sendWhiteSpace(w)
completeDoneCh := sendWhiteSpace(ctx, w)
objInfo, err := completeMultiPartUpload(ctx, bucket, object, uploadID, complMultipartUpload.Parts, opts)
// Stop writing white spaces to the client. Note that close(doneCh) style is not used as it
// can cause white space to be written after we send XML response in a race condition.