simplify URLFile (#31365)

* simplify URLFile

* more space
pull/31377/head
Greg Hogan 1 year ago committed by GitHub
parent e3028cbdca
commit ec9f3dcef3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 48
      tools/lib/url_file.py

@ -1,12 +1,10 @@
import logging import logging
import os import os
import socket
import time import time
import threading
from hashlib import sha256 from hashlib import sha256
from urllib3 import PoolManager from urllib3 import PoolManager, Retry
from urllib3.util import Timeout from urllib3.util import Timeout
from tenacity import retry, wait_random_exponential, stop_after_attempt
from typing import Optional
from openpilot.common.file_helpers import atomic_write_in_dir from openpilot.common.file_helpers import atomic_write_in_dir
from openpilot.system.hardware.hw import Paths from openpilot.system.hardware.hw import Paths
@ -25,14 +23,23 @@ class URLFileException(Exception):
pass pass
def new_pool_manager() -> PoolManager:
socket_options = [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),]
retries = Retry(total=5, backoff_factor=0.5, status_forcelist=[409, 429, 503, 504])
return PoolManager(num_pools=10, maxsize=100, socket_options=socket_options, retries=retries)
def set_pool_manager():
URLFile._pool_manager = new_pool_manager()
os.register_at_fork(after_in_child=set_pool_manager)
class URLFile: class URLFile:
_pid: Optional[int] = None _pool_manager = new_pool_manager()
_pool_manager: Optional[PoolManager] = None
_pool_manager_lock = threading.Lock()
def __init__(self, url, debug=False, cache=None): def __init__(self, url, timeout=10, debug=False, cache=None):
self._pool_manager = None
self._url = url self._url = url
self._timeout = Timeout(connect=timeout, read=timeout)
self._pos = 0 self._pos = 0
self._length = None self._length = None
self._local_file = None self._local_file = None
@ -54,20 +61,11 @@ class URLFile:
self._local_file.close() self._local_file.close()
self._local_file = None self._local_file = None
def _http_client(self) -> PoolManager: def _request(self, method, url, headers=None):
if self._pool_manager is None: return URLFile._pool_manager.request(method, url, timeout=self._timeout, headers=headers)
pid = os.getpid()
with URLFile._pool_manager_lock:
if URLFile._pid != pid or URLFile._pool_manager is None: # unsafe to share after fork
URLFile._pid = pid
URLFile._pool_manager = PoolManager(num_pools=10, maxsize=10)
self._pool_manager = URLFile._pool_manager
return self._pool_manager
@retry(wait=wait_random_exponential(multiplier=1, max=5), stop=stop_after_attempt(3), reraise=True)
def get_length_online(self): def get_length_online(self):
timeout = Timeout(connect=50.0, read=500.0) response = self._request('HEAD', self._url)
response = self._http_client().request('HEAD', self._url, timeout=timeout, preload_content=False)
if not (200 <= response.status <= 299): if not (200 <= response.status <= 299):
return -1 return -1
length = response.headers.get('content-length', 0) length = response.headers.get('content-length', 0)
@ -122,10 +120,9 @@ class URLFile:
self._pos = file_end self._pos = file_end
return response return response
@retry(wait=wait_random_exponential(multiplier=1, max=5), stop=stop_after_attempt(3), reraise=True)
def read_aux(self, ll=None): def read_aux(self, ll=None):
download_range = False download_range = False
headers = {'Connection': 'keep-alive'} headers = {}
if self._pos != 0 or ll is not None: if self._pos != 0 or ll is not None:
if ll is None: if ll is None:
end = self.get_length() - 1 end = self.get_length() - 1
@ -139,8 +136,7 @@ class URLFile:
if self._debug: if self._debug:
t1 = time.time() t1 = time.time()
timeout = Timeout(connect=50.0, read=500.0) response = self._request('GET', self._url, headers=headers)
response = self._http_client().request('GET', self._url, timeout=timeout, preload_content=False, headers=headers)
ret = response.data ret = response.data
if self._debug: if self._debug:

Loading…
Cancel
Save