Retry up to 100 times when proxying to frontend
This commit is contained in:
parent
ce153ee8f7
commit
77fe285675
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import AsyncGenerator
|
from typing import AsyncGenerator
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from starlette.types import ASGIApp
|
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||||
|
|
||||||
from .config import get_config
|
from .config import get_config
|
||||||
from .utils import console
|
from .utils import console
|
||||||
@ -15,6 +17,7 @@ from .utils import console
|
|||||||
try:
|
try:
|
||||||
from asgiproxy.config import BaseURLProxyConfigMixin, ProxyConfig
|
from asgiproxy.config import BaseURLProxyConfigMixin, ProxyConfig
|
||||||
from asgiproxy.context import ProxyContext
|
from asgiproxy.context import ProxyContext
|
||||||
|
from asgiproxy.proxies.http import proxy_http
|
||||||
from asgiproxy.simple_proxy import make_simple_proxy_app
|
from asgiproxy.simple_proxy import make_simple_proxy_app
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
||||||
@ -32,6 +35,32 @@ except ImportError:
|
|||||||
yield
|
yield
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
async def proxy_http_with_retry(
|
||||||
|
*,
|
||||||
|
context: ProxyContext,
|
||||||
|
scope: Scope,
|
||||||
|
receive: Receive,
|
||||||
|
send: Send,
|
||||||
|
) -> None:
|
||||||
|
"""Proxy an HTTP request with retries.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
context: The proxy context.
|
||||||
|
scope: The ASGI scope.
|
||||||
|
receive: The receive channel.
|
||||||
|
send: The send channel.
|
||||||
|
"""
|
||||||
|
for _attempt in range(100):
|
||||||
|
try:
|
||||||
|
return await proxy_http(
|
||||||
|
context=context, scope=scope, receive=receive, send=send
|
||||||
|
)
|
||||||
|
except aiohttp.client_exceptions.ClientError as err: # noqa: PERF203
|
||||||
|
console.debug(
|
||||||
|
f"Retrying request {scope['path']} due to client error {err!r}."
|
||||||
|
)
|
||||||
|
await asyncio.sleep(0.3)
|
||||||
|
|
||||||
def _get_proxy_app_with_context(frontend_host: str) -> tuple[ProxyContext, ASGIApp]:
|
def _get_proxy_app_with_context(frontend_host: str) -> tuple[ProxyContext, ASGIApp]:
|
||||||
"""Get the proxy app with the given frontend host.
|
"""Get the proxy app with the given frontend host.
|
||||||
|
|
||||||
@ -47,7 +76,9 @@ else:
|
|||||||
rewrite_host_header = urlparse(upstream_base_url).netloc
|
rewrite_host_header = urlparse(upstream_base_url).netloc
|
||||||
|
|
||||||
proxy_context = ProxyContext(LocalProxyConfig())
|
proxy_context = ProxyContext(LocalProxyConfig())
|
||||||
proxy_app = make_simple_proxy_app(proxy_context)
|
proxy_app = make_simple_proxy_app(
|
||||||
|
proxy_context, proxy_http_handler=proxy_http_with_retry
|
||||||
|
)
|
||||||
return proxy_context, proxy_app
|
return proxy_context, proxy_app
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
|
Loading…
Reference in New Issue
Block a user