|
35 | 35 |
|
36 | 36 | import base64 |
37 | 37 | import decimal |
38 | | -from http.client import HTTPConnection, HTTPSConnection, BadStatusLine |
| 38 | +from http.client import ( |
| 39 | + HTTPConnection, |
| 40 | + HTTPSConnection, |
| 41 | + BadStatusLine, |
| 42 | + RemoteDisconnected, |
| 43 | +) |
39 | 44 | from urllib.parse import urlparse |
40 | 45 | import logging |
41 | 46 | import simplejson as json |
| 47 | +import time |
42 | 48 |
|
43 | 49 | USER_AGENT = "AuthServiceProxy/0.1" |
44 | 50 |
|
45 | | -HTTP_TIMEOUT_IN_SECS = 900 |
| 51 | +HTTP_TIMEOUT_IN_SECS = 1000 |
| 52 | +HTTP_MAX_RETRIES = 5 |
| 53 | +HTTP_RETRY_DELAY_SECS = 2 |
| 54 | + |
46 | 55 |
|
47 | 56 | log = logging.getLogger("PastelRPC") |
48 | 57 |
|
@@ -131,22 +140,21 @@ def _request(self, method, path, postdata): |
131 | 140 | 'Authorization': self.__auth_header, |
132 | 141 | 'Connection': 'keep-alive', |
133 | 142 | 'Content-type': 'application/json'} |
134 | | - try: |
135 | | - self.__conn.request(method, path, postdata, headers) |
136 | | - return self._get_response() |
137 | | - except Exception as e: |
138 | | - # If connection was closed, try again. |
139 | | - # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset. |
140 | | - # ConnectionResetError happens on FreeBSD with Python 3.4. |
141 | | - # This can be simplified now that we depend on Python 3 (previously, we could not |
142 | | - # refer to BrokenPipeError or ConnectionResetError which did not exist on Python 2) |
143 | | - if ((isinstance(e, BadStatusLine) and (e.line == "''" or e.line == "No status line received - the server has closed the connection")) |
144 | | - or e.__class__.__name__ in ('BrokenPipeError', 'ConnectionResetError')): |
145 | | - self.__conn.close() |
| 143 | + for attempt in range(HTTP_MAX_RETRIES): |
| 144 | + try: |
146 | 145 | self.__conn.request(method, path, postdata, headers) |
147 | 146 | return self._get_response() |
148 | | - else: |
149 | | - raise |
| 147 | + except (RemoteDisconnected, BadStatusLine, ConnectionRefusedError, BrokenPipeError, ConnectionResetError) as e: |
| 148 | + if attempt < HTTP_MAX_RETRIES - 1: |
| 149 | + log.warning(f"Attempt {attempt + 1} failed: {e}. Retrying in {HTTP_RETRY_DELAY_SECS} seconds...") |
| 150 | + self.__conn.close() |
| 151 | + time.sleep(HTTP_RETRY_DELAY_SECS) |
| 152 | + else: |
| 153 | + log.error(f"All {HTTP_MAX_RETRIES} attempts failed. Raising exception.") |
| 154 | + raise |
| 155 | + except Exception as e: |
| 156 | + log.error(f"Unhandled exception: {e}. Raising exception.") |
| 157 | + raise |
150 | 158 |
|
151 | 159 |
|
152 | 160 | def __call__(self, *args): |
|
0 commit comments