Do not assume all HTTP errors as Network errors (#7983)

In situations such as when client uploading data,
prematurely disconnects from server such as pressing
ctrl-c before uploading all the data. Under this
situation in distributed setup we prematurely
disconnect disks causing a reconnect loop. This has
an adverse affect we end up leaving a lot of files
in temporary location which ideally should have been
cleaned up when Put() prematurely fails.

This is also a regression which got introduced in #7610
master
Harshavardhana 5 years ago committed by kannappanr
parent 94c88890b8
commit 54eded2e6f
  1. 2
      cmd/object-api-common.go
  2. 4
      cmd/storage-rest-client.go
  3. 38
      cmd/utils.go

@ -129,7 +129,7 @@ func cleanupDir(ctx context.Context, storage StorageAPI, volume, dirPath string)
// Entry path is empty, just delete it. // Entry path is empty, just delete it.
if len(entries) == 0 { if len(entries) == 0 {
err = storage.DeleteFile(volume, path.Clean(entryPath)) err = storage.DeleteFile(volume, entryPath)
logger.LogIf(ctx, err) logger.LogIf(ctx, err)
return err return err
} }

@ -44,8 +44,8 @@ func isNetworkError(err error) bool {
if err.Error() == errConnectionStale.Error() { if err.Error() == errConnectionStale.Error() {
return true return true
} }
if _, ok := err.(*rest.NetworkError); ok { if nerr, ok := err.(*rest.NetworkError); ok {
return true return isNetworkOrHostDown(nerr.Err)
} }
return false return false
} }

@ -29,7 +29,6 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
@ -443,30 +442,21 @@ func isNetworkOrHostDown(err error) bool {
if err == nil { if err == nil {
return false return false
} }
switch err.(type) { // We need to figure if the error either a timeout
case *net.DNSError, *net.OpError, net.UnknownNetworkError: // or a non-temporary error.
return true e, ok := err.(net.Error)
case *url.Error: if ok {
// For a URL error, where it replies back "connection closed" return e.Timeout()
if strings.Contains(err.Error(), "Connection closed by foreign host") {
return true
}
return true
default:
if strings.Contains(err.Error(), "net/http: TLS handshake timeout") {
// If error is - tlsHandshakeTimeoutError,.
return true
} else if strings.Contains(err.Error(), "i/o timeout") {
// If error is - tcp timeoutError.
return true
} else if strings.Contains(err.Error(), "connection timed out") {
// If err is a net.Dial timeout.
return true
} else if strings.Contains(err.Error(), "net/http: HTTP/1.x transport connection broken") {
return true
}
} }
return false // Fallback to other mechanisms.
if strings.Contains(err.Error(), "i/o timeout") {
// If error is - tcp timeoutError.
ok = true
} else if strings.Contains(err.Error(), "connection timed out") {
// If err is a net.Dial timeout.
ok = true
}
return ok
} }
// Used for registering with rest handlers (have a look at registerStorageRESTHandlers for usage example) // Used for registering with rest handlers (have a look at registerStorageRESTHandlers for usage example)

Loading…
Cancel
Save