mirror of
				https://github.com/openSUSE/osc.git
				synced 2025-10-31 19:42:16 +01:00 
			
		
		
		
	Implement retries in 'git-obs'
This commit is contained in:
		| @@ -1,18 +1,17 @@ | ||||
| import copy | ||||
| import http.client | ||||
| import json | ||||
| import time | ||||
| import urllib.parse | ||||
| from typing import Optional | ||||
|  | ||||
| import urllib3 | ||||
| import urllib3.exceptions | ||||
| import urllib3.response | ||||
|  | ||||
| from .conf import Login | ||||
|  | ||||
|  | ||||
| # TODO: retry, backoff, connection pool? | ||||
|  | ||||
|  | ||||
| class GiteaHTTPResponse: | ||||
|     """ | ||||
|     A ``urllib3.response.HTTPResponse`` wrapper | ||||
| @@ -52,6 +51,16 @@ class Connection: | ||||
|         self.port = alternative_port if alternative_port else parsed_url.port | ||||
|         self.conn = ConnectionClass(host=self.host, port=self.port) | ||||
|  | ||||
|         # retries; variables are named according to urllib3 | ||||
|         self.retry_count = 3 | ||||
|         self.retry_backoff_factor = 2 | ||||
|         self.retry_status_forcelist = ( | ||||
|             500,  # Internal Server Error | ||||
|             502,  # Bad Gateway | ||||
|             503,  # Service Unavailable | ||||
|             504,  # Gateway Timeout | ||||
|         ) | ||||
|  | ||||
|         if hasattr(self.conn, "set_cert"): | ||||
|             # needed to avoid: AttributeError: 'HTTPSConnection' object has no attribute 'assert_hostname'. Did you mean: 'server_hostname'? | ||||
|             self.conn.set_cert() | ||||
| @@ -95,8 +104,27 @@ class Connection: | ||||
|  | ||||
|         body = json.dumps(json_data) if json_data else None | ||||
|  | ||||
|         self.conn.request(method, url, body, headers) | ||||
|         response = self.conn.getresponse() | ||||
|         for retry in range(1 + self.retry_count): | ||||
|             # 1 regular request + ``self.retry_count`` retries | ||||
|             try: | ||||
|                 self.conn.request(method, url, body, headers) | ||||
|                 response = self.conn.getresponse() | ||||
|  | ||||
|                 if response.status not in self.retry_status_forcelist: | ||||
|                     # we are happy with the response status -> use the response | ||||
|                     break | ||||
|  | ||||
|                 if retry >= self.retry_count: | ||||
|                     # we have reached maximum number of retries -> use the response | ||||
|                     break | ||||
|  | ||||
|             except (urllib3.exceptions.HTTPError, ConnectionResetError): | ||||
|                 if retry >= self.retry_count: | ||||
|                     raise | ||||
|  | ||||
|             # {backoff factor} * (2 ** ({number of previous retries})) | ||||
|             time.sleep(self.retry_backoff_factor * (2 ** retry)) | ||||
|             self.conn.close() | ||||
|  | ||||
|         if isinstance(response, http.client.HTTPResponse): | ||||
|             result = GiteaHTTPResponse(urllib3.response.HTTPResponse.from_httplib(response)) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user