terrasync.py: improve retry logic and error handling
- Add method assembleUrl() to HTTPGetter. - Raise a NetworkError exception with the particular URL and number of retries when it has been exhausted. - Number of retries is now trivial to expose as a parameter, and set to 5 in HTTPGetter. - Sleep for one second between self.httpConnection.close() and self.httpConnection.connect() when retrying a failed HTTP request. - Apply DRY principle.
This commit is contained in:
parent
c27ae92c73
commit
2c6f93aa46
1 changed files with 28 additions and 12 deletions
|
@ -28,6 +28,7 @@ from os.path import isfile, isdir, join
|
||||||
import re
|
import re
|
||||||
import argparse
|
import argparse
|
||||||
import shutil
|
import shutil
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
# Generic exception class for terrasync.py, to be subclassed for each specific
|
# Generic exception class for terrasync.py, to be subclassed for each specific
|
||||||
|
@ -90,9 +91,12 @@ class HTTPGetter:
|
||||||
self.httpConnection = HTTPConnection(self.parsedBaseUrl.netloc)
|
self.httpConnection = HTTPConnection(self.parsedBaseUrl.netloc)
|
||||||
self.httpRequestHeaders = headers = {'Host':self.parsedBaseUrl.netloc,'Content-Length':0,'Connection':'Keep-Alive','User-Agent':'FlightGear terrasync.py'}
|
self.httpRequestHeaders = headers = {'Host':self.parsedBaseUrl.netloc,'Content-Length':0,'Connection':'Keep-Alive','User-Agent':'FlightGear terrasync.py'}
|
||||||
|
|
||||||
|
def assembleUrl(self, httpGetCallback):
|
||||||
|
return self.parsedBaseUrl.path + httpGetCallback.src
|
||||||
|
|
||||||
def doGet(self, httpGetCallback):
|
def doGet(self, httpGetCallback):
|
||||||
conn = self.httpConnection
|
conn = self.httpConnection
|
||||||
url = self.parsedBaseUrl.path + httpGetCallback.src
|
url = self.assembleUrl(httpGetCallback)
|
||||||
self.httpConnection.request("GET", url, None, self.httpRequestHeaders)
|
self.httpConnection.request("GET", url, None, self.httpRequestHeaders)
|
||||||
httpResponse = self.httpConnection.getresponse()
|
httpResponse = self.httpConnection.getresponse()
|
||||||
|
|
||||||
|
@ -100,16 +104,24 @@ class HTTPGetter:
|
||||||
return httpGetCallback.callback(url, httpResponse)
|
return httpGetCallback.callback(url, httpResponse)
|
||||||
|
|
||||||
def get(self, httpGetCallback):
|
def get(self, httpGetCallback):
|
||||||
try:
|
nbRetries = nbRetriesLeft = 5
|
||||||
res = self.doGet(httpGetCallback)
|
|
||||||
except HTTPException:
|
|
||||||
# try to reconnect once
|
|
||||||
#print("reconnect")
|
|
||||||
self.httpConnection.close()
|
|
||||||
self.httpConnection.connect()
|
|
||||||
res = self.doGet(httpGetCallback)
|
|
||||||
|
|
||||||
return res
|
while True:
|
||||||
|
try:
|
||||||
|
return self.doGet(httpGetCallback)
|
||||||
|
except HTTPException as exc:
|
||||||
|
if nbRetriesLeft == 0:
|
||||||
|
raise NetworkError(
|
||||||
|
"after {nbRetries} retries for URL {url}: {errMsg}"
|
||||||
|
.format(nbRetries=nbRetries,
|
||||||
|
url=self.assembleUrl(httpGetCallback),
|
||||||
|
errMsg=exc)) from exc
|
||||||
|
|
||||||
|
# Try to reconnect
|
||||||
|
self.httpConnection.close()
|
||||||
|
time.sleep(1)
|
||||||
|
self.httpConnection.connect()
|
||||||
|
nbRetriesLeft -= 1
|
||||||
|
|
||||||
|
|
||||||
#################################################################################################################################
|
#################################################################################################################################
|
||||||
|
@ -176,8 +188,12 @@ class HTTPDownloadRequest(HTTPGetCallback):
|
||||||
raise NetworkError("HTTP callback got status {status} for URL {url}"
|
raise NetworkError("HTTP callback got status {status} for URL {url}"
|
||||||
.format(status=httpResponse.status, url=url))
|
.format(status=httpResponse.status, url=url))
|
||||||
|
|
||||||
|
try:
|
||||||
with open(self.dst, 'wb') as f:
|
with open(self.dst, 'wb') as f:
|
||||||
f.write(httpResponse.read())
|
f.write(httpResponse.read())
|
||||||
|
except HTTPException as exc:
|
||||||
|
raise NetworkError("for URL {url}: {error}"
|
||||||
|
.format(url=url, error=exc)) from exc
|
||||||
|
|
||||||
if self.mycallback != None:
|
if self.mycallback != None:
|
||||||
self.mycallback(self)
|
self.mycallback(self)
|
||||||
|
|
Loading…
Reference in a new issue