mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 12:05:07 +00:00
fix(session): cap Retry-After on the requests retry policies
A server-sent Retry-After could park a run for up to six hours.
This commit is contained in:
@@ -6,7 +6,9 @@ from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from unshackle.core.session import RnetSession
|
||||
from unshackle.core.providers.imdb import IMDBProvider
|
||||
from unshackle.core.service import Service
|
||||
from unshackle.core.session import MAX_BACKOFF, RnetSession
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -67,3 +69,15 @@ def test_exponential_backoff_without_retry_after(session):
|
||||
|
||||
def test_no_response_still_backs_off(session):
|
||||
assert session.get_sleep_time(None, 30) == session.max_backoff
|
||||
|
||||
|
||||
def test_service_session_caps_retry_after():
|
||||
retry = Service.get_session().get_adapter("https://example.invalid/").max_retries
|
||||
assert retry.respect_retry_after_header
|
||||
assert retry.retry_after_max == MAX_BACKOFF
|
||||
|
||||
|
||||
def test_provider_session_gives_up_on_a_rate_limit():
|
||||
retry = IMDBProvider().session.get_adapter("https://example.invalid/").max_retries
|
||||
assert not retry.respect_retry_after_header
|
||||
assert 429 not in retry.status_forcelist
|
||||
|
||||
@@ -61,7 +61,7 @@ class MetadataProvider(metaclass=ABCMeta):
|
||||
retry = Retry(
|
||||
total=3,
|
||||
backoff_factor=1,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
status_forcelist=[500, 502, 503, 504],
|
||||
allowed_methods=["GET", "POST"],
|
||||
respect_retry_after_header=False,
|
||||
)
|
||||
|
||||
@@ -38,6 +38,7 @@ from unshackle.core.console import console, prompt_user
|
||||
from unshackle.core.constants import AnyTrack
|
||||
from unshackle.core.credential import Credential
|
||||
from unshackle.core.proxies.resolve import is_loopback
|
||||
from unshackle.core.session import MAX_BACKOFF
|
||||
from unshackle.core.titles import Title_T, Titles_T, remap_titles
|
||||
from unshackle.core.titles.episode import Episode, Series
|
||||
from unshackle.core.titles.movie import Movie, Movies
|
||||
@@ -921,7 +922,12 @@ class RemoteService:
|
||||
self._session.mount(
|
||||
"https://",
|
||||
HTTPAdapter(
|
||||
max_retries=Retry(total=5, backoff_factor=0.2, status_forcelist=[429, 500, 502, 503, 504]),
|
||||
max_retries=Retry(
|
||||
total=5,
|
||||
backoff_factor=0.2,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
retry_after_max=MAX_BACKOFF,
|
||||
),
|
||||
pool_maxsize=64,
|
||||
pool_block=True,
|
||||
),
|
||||
|
||||
@@ -431,6 +431,7 @@ class Service(metaclass=ABCMeta):
|
||||
status_forcelist=STATUS_FORCELIST,
|
||||
allowed_methods=RETRY_METHODS,
|
||||
respect_retry_after_header=True,
|
||||
retry_after_max=MAX_BACKOFF,
|
||||
),
|
||||
pool_connections=POOL_MAX_SIZE,
|
||||
pool_maxsize=POOL_MAX_SIZE,
|
||||
|
||||
@@ -31,7 +31,7 @@ from unshackle.core.downloaders import requests
|
||||
from unshackle.core.drm import DRM_T, ClearKeyCENC, PlayReady, Widevine
|
||||
from unshackle.core.drm.verify import decrypt_track
|
||||
from unshackle.core.events import events
|
||||
from unshackle.core.session import RnetSession, utf8_text
|
||||
from unshackle.core.session import MAX_BACKOFF, RnetSession, utf8_text
|
||||
from unshackle.core.tracks import resume
|
||||
from unshackle.core.utilities import get_boxes, log_event, try_ensure_utf8
|
||||
from unshackle.core.utils.subprocess import ffprobe
|
||||
@@ -78,7 +78,12 @@ def direct_session(session: Union[Session, "RnetSession"], proxy: Optional[str]
|
||||
new.mount(
|
||||
"https://",
|
||||
HTTPAdapter(
|
||||
max_retries=Retry(total=5, backoff_factor=0.2, status_forcelist=[429, 500, 502, 503, 504]),
|
||||
max_retries=Retry(
|
||||
total=5,
|
||||
backoff_factor=0.2,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
retry_after_max=MAX_BACKOFF,
|
||||
),
|
||||
pool_maxsize=64,
|
||||
pool_block=True,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user