mirror of
https://github.com/esphome/esphome.git
synced 2026-09-17 18:18:43 +00:00
Merge remote-tracking branch 'origin/external-files-parallel' into integration
# Conflicts: # esphome/external_files.py
This commit is contained in:
@@ -88,7 +88,9 @@ def _write_etag(local_file_path: Path, etag: str | None) -> None:
|
||||
)
|
||||
|
||||
|
||||
def has_remote_file_changed(url: str, local_file_path: Path) -> bool:
|
||||
def has_remote_file_changed(
|
||||
url: str, local_file_path: Path, timeout: int = NETWORK_TIMEOUT
|
||||
) -> bool:
|
||||
if local_file_path.exists():
|
||||
_LOGGER.debug("has_remote_file_changed: File exists at %s", local_file_path)
|
||||
try:
|
||||
@@ -104,7 +106,7 @@ def has_remote_file_changed(url: str, local_file_path: Path) -> bool:
|
||||
if etag := _read_etag(local_file_path):
|
||||
headers[IF_NONE_MATCH] = etag
|
||||
response = requests.head(
|
||||
url, headers=headers, timeout=NETWORK_TIMEOUT, allow_redirects=True
|
||||
url, headers=headers, timeout=timeout, allow_redirects=True
|
||||
)
|
||||
|
||||
_LOGGER.debug(
|
||||
@@ -156,7 +158,7 @@ def download_content(url: str, path: Path, timeout: int = NETWORK_TIMEOUT) -> by
|
||||
if CORE.skip_external_update and path.exists():
|
||||
_LOGGER.debug("Skipping update for %s (refresh disabled)", url)
|
||||
return path.read_bytes()
|
||||
if not has_remote_file_changed(url, path):
|
||||
if not has_remote_file_changed(url, path, timeout):
|
||||
_LOGGER.debug("Remote file has not changed %s", url)
|
||||
return path.read_bytes()
|
||||
|
||||
@@ -224,15 +226,17 @@ def download_content_many(
|
||||
path, url = next(iter(seen.items()))
|
||||
download_content(url, path, timeout)
|
||||
return
|
||||
|
||||
def _download_one(path_url: tuple[Path, str]) -> None:
|
||||
# `seen` stores entries as (path, url) so the dict can dedupe by
|
||||
# path; flip them back to download_content's (url, path) order.
|
||||
path, url = path_url
|
||||
download_content(url, path, timeout)
|
||||
|
||||
workers = max(1, min(max_workers, len(seen)))
|
||||
with ThreadPoolExecutor(max_workers=workers) as ex:
|
||||
# list() forces iteration so exceptions surface here, not silently.
|
||||
list(
|
||||
ex.map(
|
||||
lambda item: download_content(item[1], item[0], timeout),
|
||||
seen.items(),
|
||||
)
|
||||
)
|
||||
list(ex.map(_download_one, seen.items()))
|
||||
|
||||
|
||||
# Each component that uses external_files defines its own local
|
||||
|
||||
Reference in New Issue
Block a user