Files
zulip/zerver/lib/outgoing_http.py
Alex Vandiver bf9780267d outgoing_http: Give an easy way to configure retries.
The default is kept as no retries.  Since retries with exponential
backoff are a good thing to make easy, the int form defaults to
setting a backoff_factor.

Unfortunately, urllib3 retry backoff does not implement jitter.
Switching this to use the `backoff` library[1] rather than urllib3's
native Retry is left as future extension.

[1] https://pypi.org/project/backoff/
2021-09-01 05:34:13 -07:00

45 lines
1.4 KiB
Python

from typing import Any, Dict, Optional, Union
import requests
from requests.packages.urllib3.util.retry import Retry
class OutgoingSession(requests.Session):
def __init__(
self,
role: str,
timeout: int,
headers: Optional[Dict[str, str]] = None,
max_retries: Optional[Union[int, Retry]] = None,
) -> None:
super().__init__()
retry: Optional[Retry] = Retry(total=0)
if max_retries is not None:
if isinstance(max_retries, Retry):
retry = max_retries
else:
retry = Retry(total=max_retries, backoff_factor=1)
outgoing_adapter = OutgoingHTTPAdapter(role=role, timeout=timeout, max_retries=retry)
self.mount("http://", outgoing_adapter)
self.mount("https://", outgoing_adapter)
if headers:
self.headers.update(headers)
class OutgoingHTTPAdapter(requests.adapters.HTTPAdapter):
role: str
timeout: int
def __init__(self, role: str, timeout: int, max_retries: Optional[Retry]) -> None:
self.role = role
self.timeout = timeout
super().__init__(max_retries=max_retries)
def send(self, *args: Any, **kwargs: Any) -> requests.Response:
if kwargs.get("timeout") is None:
kwargs["timeout"] = self.timeout
return super().send(*args, **kwargs)
def proxy_headers(self, proxy: str) -> Dict[str, str]:
return {"X-Smokescreen-Role": self.role}