mirror of
https://github.com/Horizontal42/Sort_YM.git
synced 2026-11-10 15:42:02 +03:00
Медленная/нестабильная сеть до api.music.yandex.net роняла весь процесс при первом же таймауте (5с по умолчанию у библиотеки). Добавлен with_retries с экспоненциальной паузой на всех сетевых точках входа (fetch, language, genres, apply, client.init), таймаут запроса поднят до 20с (настраивается в config.toml). Заодно поправлен скрытый баг: language.py раньше кэшировал таймаут как "текста нет" навсегда - теперь только настоящий NotFoundError трактуется так.
44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
from __future__ import annotations
|
||
|
||
import time
|
||
from typing import Callable, Iterator, List, TypeVar
|
||
|
||
from yandex_music import Client
|
||
from yandex_music.exceptions import NetworkError, NotFoundError
|
||
|
||
T = TypeVar("T")
|
||
|
||
|
||
def make_client(token: str, request_timeout: float = 20) -> Client:
|
||
client = Client(token=token)
|
||
client.request.set_timeout(request_timeout)
|
||
with_retries(lambda: client.init())
|
||
return client
|
||
|
||
|
||
def chunked(items: List[T], size: int) -> Iterator[List[T]]:
|
||
for i in range(0, len(items), size):
|
||
yield items[i : i + size]
|
||
|
||
|
||
def with_retries(fn: Callable[[], T], max_attempts: int = 4, base_delay: float = 2.0) -> T:
|
||
"""Повторяет вызов при временных сетевых сбоях (таймауты и т.п.) с экспоненциальной паузой.
|
||
|
||
NotFoundError не повторяется - это окончательный ответ API, а не сбой сети,
|
||
хотя формально он тоже унаследован от NetworkError.
|
||
"""
|
||
last_exc: NetworkError | None = None
|
||
for attempt in range(max_attempts):
|
||
try:
|
||
return fn()
|
||
except NotFoundError:
|
||
raise
|
||
except NetworkError as e:
|
||
last_exc = e
|
||
if attempt < max_attempts - 1:
|
||
wait = base_delay * (2**attempt)
|
||
print(f" сетевая ошибка ({e}), повтор через {wait:.0f}с...")
|
||
time.sleep(wait)
|
||
|
||
assert last_exc is not None
|
||
raise last_exc
|