1
0
mirror of https://github.com/gilbertchen/duplicacy synced 2025-12-06 00:03:38 +00:00

Improve OneDrive backend by retrying on more errors

This commit is contained in:
Gilbert Chen
2017-07-19 23:39:54 -04:00
parent 9be4927c87
commit f3447bb611

View File

@@ -9,6 +9,7 @@ import (
"time"
"sync"
"bytes"
"strings"
"io/ioutil"
"encoding/json"
"io"
@@ -41,6 +42,7 @@ type OneDriveClient struct {
Token *oauth2.Token
TokenLock *sync.Mutex
IsConnected bool
TestMode bool
}
@@ -115,9 +117,27 @@ func (client *OneDriveClient) call(url string, method string, input interface{},
response, err = client.HTTPClient.Do(request)
if err != nil {
if client.IsConnected {
if strings.Contains(err.Error(), "TLS handshake timeout") {
// Give a long timeout regardless of backoff when a TLS timeout happens, hoping that
// idle connections are not to be reused on reconnect.
retryAfter := time.Duration(rand.Float32() * 60000 + 180000)
LOG_INFO("ONEDRIVE_RETRY", "TLS handshake timeout; retry after %d milliseconds", retryAfter)
time.Sleep(retryAfter * time.Millisecond)
} else {
// For all other errors just blindly retry until the maximum is reached
retryAfter := time.Duration(rand.Float32() * 1000.0 * float32(backoff))
LOG_INFO("ONEDRIVE_RETRY", "%v; retry after %d milliseconds", err, retryAfter)
time.Sleep(retryAfter * time.Millisecond)
}
backoff *= 2
continue
}
return nil, 0, err
}
client.IsConnected = true
if response.StatusCode < 400 {
return response.Body, response.ContentLength, nil
}
@@ -139,9 +159,9 @@ func (client *OneDriveClient) call(url string, method string, input interface{},
return nil, 0, err
}
continue
} else if response.StatusCode == 500 || response.StatusCode == 503 || response.StatusCode == 509 {
} else if response.StatusCode > 401 && response.StatusCode != 404 {
retryAfter := time.Duration(rand.Float32() * 1000.0 * float32(backoff))
LOG_INFO("ONEDRIVE_RETRY", "Response status: %d; retry after %d milliseconds", response.StatusCode, retryAfter)
LOG_INFO("ONEDRIVE_RETRY", "Response code: %d; retry after %d milliseconds", response.StatusCode, retryAfter)
time.Sleep(retryAfter * time.Millisecond)
backoff *= 2
continue
@@ -151,7 +171,6 @@ func (client *OneDriveClient) call(url string, method string, input interface{},
}
errorResponse.Error.Status = response.StatusCode
return nil, 0, errorResponse.Error
}
}
@@ -169,7 +188,7 @@ func (client *OneDriveClient) RefreshToken() (err error) {
readCloser, _, err := client.call(OneDriveRefreshTokenURL, "POST", client.Token, "")
if err != nil {
return err
return fmt.Errorf("failed to refresh the access token: %v", err)
}
defer readCloser.Close()