heal: Set truncate when no more walk entries (#3932)

master
Anis Elleuch 8 years ago committed by Harshavardhana
parent eb02261642
commit 9d6e226692
  1. 39
      cmd/admin-handlers_test.go
  2. 25
      cmd/xl-v1-list-objects-heal.go

@ -26,6 +26,7 @@ import (
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
"reflect"
"testing" "testing"
"time" "time"
@ -1451,6 +1452,7 @@ func TestListHealUploadsHandler(t *testing.T) {
delimiter string delimiter string
maxKeys string maxKeys string
statusCode int statusCode int
expectedResp ListMultipartUploadsResponse
}{ }{
// 1. Valid params. // 1. Valid params.
{ {
@ -1460,6 +1462,14 @@ func TestListHealUploadsHandler(t *testing.T) {
delimiter: "/", delimiter: "/",
maxKeys: "10", maxKeys: "10",
statusCode: http.StatusOK, statusCode: http.StatusOK,
expectedResp: ListMultipartUploadsResponse{
XMLName: xml.Name{Space: "http://s3.amazonaws.com/doc/2006-03-01/", Local: "ListMultipartUploadsResult"},
Bucket: "mybucket",
KeyMarker: "prefix11",
Delimiter: "/",
Prefix: "prefix",
MaxUploads: 10,
},
}, },
// 2. Valid params with empty prefix. // 2. Valid params with empty prefix.
{ {
@ -1469,6 +1479,14 @@ func TestListHealUploadsHandler(t *testing.T) {
delimiter: "/", delimiter: "/",
maxKeys: "10", maxKeys: "10",
statusCode: http.StatusOK, statusCode: http.StatusOK,
expectedResp: ListMultipartUploadsResponse{
XMLName: xml.Name{Space: "http://s3.amazonaws.com/doc/2006-03-01/", Local: "ListMultipartUploadsResult"},
Bucket: "mybucket",
KeyMarker: "",
Delimiter: "/",
Prefix: "",
MaxUploads: 10,
},
}, },
// 3. Invalid params with invalid bucket. // 3. Invalid params with invalid bucket.
{ {
@ -1536,8 +1554,29 @@ func TestListHealUploadsHandler(t *testing.T) {
rec := httptest.NewRecorder() rec := httptest.NewRecorder()
adminTestBed.mux.ServeHTTP(rec, req) adminTestBed.mux.ServeHTTP(rec, req)
if test.statusCode != rec.Code { if test.statusCode != rec.Code {
t.Errorf("Test %d - Expected HTTP status code %d but received %d", i+1, test.statusCode, rec.Code) t.Errorf("Test %d - Expected HTTP status code %d but received %d", i+1, test.statusCode, rec.Code)
} }
// Compare result with the expected one only when we receive 200 OK
if rec.Code == http.StatusOK {
resp := rec.Result()
xmlBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Errorf("Test %d: Failed to read response %v", i+1, err)
}
var actualResult ListMultipartUploadsResponse
err = xml.Unmarshal(xmlBytes, &actualResult)
if err != nil {
t.Errorf("Test %d: Failed to unmarshal xml %v", i+1, err)
}
if !reflect.DeepEqual(test.expectedResp, actualResult) {
t.Fatalf("Test %d: Unexpected response `%+v`, expected: `%+v`", i+1, test.expectedResp, actualResult)
}
}
} }
} }

@ -303,6 +303,8 @@ func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker,
var walkerDoneCh chan struct{} var walkerDoneCh chan struct{}
// Check if we have room left to send more uploads. // Check if we have room left to send more uploads.
if maxUploads > 0 { if maxUploads > 0 {
uploadsLeft := maxUploads
walkerCh, walkerDoneCh = xl.listPool.Release(listParams{ walkerCh, walkerDoneCh = xl.listPool.Release(listParams{
bucket: minioMetaMultipartBucket, bucket: minioMetaMultipartBucket,
recursive: recursive, recursive: recursive,
@ -319,10 +321,14 @@ func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker,
multipartPrefixPath, multipartMarkerPath, multipartPrefixPath, multipartMarkerPath,
recursive, listDir, isLeaf, walkerDoneCh) recursive, listDir, isLeaf, walkerDoneCh)
} }
// Collect uploads until maxUploads limit is reached. // Collect uploads until leftUploads limit is reached.
for walkResult := range walkerCh { for {
// For any error during tree walk we should walkResult, ok := <-walkerCh
// return right away. if !ok {
truncated = false
break
}
// For any error during tree walk, we should return right away.
if walkResult.err != nil { if walkResult.err != nil {
return ListMultipartsInfo{}, walkResult.err return ListMultipartsInfo{}, walkResult.err
} }
@ -334,8 +340,8 @@ func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker,
uploads = append(uploads, uploadMetadata{ uploads = append(uploads, uploadMetadata{
Object: entry, Object: entry,
}) })
maxUploads-- uploadsLeft--
if maxUploads == 0 { if uploadsLeft == 0 {
break break
} }
continue continue
@ -347,20 +353,21 @@ func (xl xlObjects) listMultipartUploadsHeal(bucket, prefix, keyMarker,
var end bool var end bool
uploadIDMarker = "" uploadIDMarker = ""
newUploads, end, err = fetchMultipartUploadIDs(bucket, entry, uploadIDMarker, newUploads, end, err = fetchMultipartUploadIDs(bucket, entry, uploadIDMarker,
maxUploads, xl.getLoadBalancedDisks()) uploadsLeft, xl.getLoadBalancedDisks())
if err != nil { if err != nil {
return ListMultipartsInfo{}, err return ListMultipartsInfo{}, err
} }
uploads = append(uploads, newUploads...) uploads = append(uploads, newUploads...)
maxUploads -= len(newUploads) uploadsLeft -= len(newUploads)
if end && walkResult.end { if end && walkResult.end {
truncated = false truncated = false
break break
} }
if maxUploads == 0 { if uploadsLeft == 0 {
break break
} }
} }
} }
// For all received uploads fill in the multiparts result. // For all received uploads fill in the multiparts result.

Loading…
Cancel
Save