|
|
@ -61,7 +61,6 @@ func waitForLowHTTPReq(maxIO int, maxWait time.Duration) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// At max 10 attempts to wait with 100 millisecond interval before proceeding
|
|
|
|
// At max 10 attempts to wait with 100 millisecond interval before proceeding
|
|
|
|
waitCount := 10 |
|
|
|
|
|
|
|
waitTick := 100 * time.Millisecond |
|
|
|
waitTick := 100 * time.Millisecond |
|
|
|
|
|
|
|
|
|
|
|
// Bucket notification and http trace are not costly, it is okay to ignore them
|
|
|
|
// Bucket notification and http trace are not costly, it is okay to ignore them
|
|
|
@ -70,14 +69,21 @@ func waitForLowHTTPReq(maxIO int, maxWait time.Duration) { |
|
|
|
return maxIO + int(globalHTTPListen.NumSubscribers()) + int(globalHTTPTrace.NumSubscribers()) |
|
|
|
return maxIO + int(globalHTTPListen.NumSubscribers()) + int(globalHTTPTrace.NumSubscribers()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tmpMaxWait := maxWait |
|
|
|
if httpServer := newHTTPServerFn(); httpServer != nil { |
|
|
|
if httpServer := newHTTPServerFn(); httpServer != nil { |
|
|
|
// Any requests in progress, delay the heal.
|
|
|
|
// Any requests in progress, delay the heal.
|
|
|
|
for httpServer.GetRequestCount() >= maxIOFn() { |
|
|
|
for httpServer.GetRequestCount() >= maxIOFn() { |
|
|
|
|
|
|
|
if tmpMaxWait > 0 { |
|
|
|
|
|
|
|
if tmpMaxWait < waitTick { |
|
|
|
|
|
|
|
time.Sleep(tmpMaxWait) |
|
|
|
|
|
|
|
} else { |
|
|
|
time.Sleep(waitTick) |
|
|
|
time.Sleep(waitTick) |
|
|
|
waitCount-- |
|
|
|
} |
|
|
|
if waitCount == 0 { |
|
|
|
tmpMaxWait = tmpMaxWait - waitTick |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if tmpMaxWait <= 0 { |
|
|
|
if intDataUpdateTracker.debug { |
|
|
|
if intDataUpdateTracker.debug { |
|
|
|
logger.Info("waitForLowHTTPReq: waited %d times, resuming", waitCount) |
|
|
|
logger.Info("waitForLowHTTPReq: waited max %s, resuming", maxWait) |
|
|
|
} |
|
|
|
} |
|
|
|
break |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
@ -91,21 +97,23 @@ func (h *healRoutine) run(ctx context.Context, objAPI ObjectLayer) { |
|
|
|
select { |
|
|
|
select { |
|
|
|
case task, ok := <-h.tasks: |
|
|
|
case task, ok := <-h.tasks: |
|
|
|
if !ok { |
|
|
|
if !ok { |
|
|
|
break |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var res madmin.HealResultItem |
|
|
|
var res madmin.HealResultItem |
|
|
|
var err error |
|
|
|
var err error |
|
|
|
switch { |
|
|
|
switch task.bucket { |
|
|
|
case task.bucket == nopHeal: |
|
|
|
case nopHeal: |
|
|
|
continue |
|
|
|
continue |
|
|
|
case task.bucket == SlashSeparator: |
|
|
|
case SlashSeparator: |
|
|
|
res, err = healDiskFormat(ctx, objAPI, task.opts) |
|
|
|
res, err = healDiskFormat(ctx, objAPI, task.opts) |
|
|
|
case task.bucket != "" && task.object == "": |
|
|
|
default: |
|
|
|
|
|
|
|
if task.object == "" { |
|
|
|
res, err = objAPI.HealBucket(ctx, task.bucket, task.opts) |
|
|
|
res, err = objAPI.HealBucket(ctx, task.bucket, task.opts) |
|
|
|
case task.bucket != "" && task.object != "": |
|
|
|
} else { |
|
|
|
res, err = objAPI.HealObject(ctx, task.bucket, task.object, task.versionID, task.opts) |
|
|
|
res, err = objAPI.HealObject(ctx, task.bucket, task.object, task.versionID, task.opts) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
task.responseCh <- healResult{result: res, err: err} |
|
|
|
task.responseCh <- healResult{result: res, err: err} |
|
|
|
|
|
|
|
|
|
|
|
case <-h.doneCh: |
|
|
|
case <-h.doneCh: |
|
|
|