fix(payments): restore default provider connections
This commit is contained in:
@@ -5,15 +5,10 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any, Callable, Dict, Mapping, Optional, Tuple
|
from typing import Any, Callable, Dict, Mapping, Optional, Tuple
|
||||||
|
|
||||||
from aiohttp import ClientError, ClientSession, ClientTimeout, TCPConnector, TraceConfig
|
from aiohttp import ClientError, ClientSession, ClientTimeout, TraceConfig
|
||||||
|
|
||||||
SuccessCheck = Callable[[int, Any], bool]
|
SuccessCheck = Callable[[int, Any], bool]
|
||||||
_TRANSPORT_ATTEMPTS = 2
|
_TRANSPORT_ATTEMPTS = 2
|
||||||
_PAYMENT_REQUEST_USER_AGENT = (
|
|
||||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
|
||||||
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
|
||||||
"Chrome/125.0.0.0 Safari/537.36"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def http_ok(status: int, _body: Any) -> bool:
|
def http_ok(status: int, _body: Any) -> bool:
|
||||||
@@ -120,27 +115,21 @@ class HttpClientMixin:
|
|||||||
``__init__`` and inherits ``_get_session`` / ``close``. The session is
|
``__init__`` and inherits ``_get_session`` / ``close``. The session is
|
||||||
created on first use and recreated transparently if it was closed.
|
created on first use and recreated transparently if it was closed.
|
||||||
|
|
||||||
Payment provider calls are infrequent but user-facing, so the default
|
Provider API calls are traced so callers can retry transport failures only
|
||||||
connector does not reuse TCP connections. This avoids intermittent hangs
|
when aiohttp has not sent request headers yet.
|
||||||
on stale keep-alive sockets after long idle periods.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_timeout: ClientTimeout
|
_timeout: ClientTimeout
|
||||||
_session: Optional[ClientSession]
|
_session: Optional[ClientSession]
|
||||||
_connector_force_close: bool
|
|
||||||
|
|
||||||
def _init_http_client(self, *, total_timeout: float = 20.0) -> None:
|
def _init_http_client(self, *, total_timeout: float = 20.0) -> None:
|
||||||
self._timeout = ClientTimeout(total=total_timeout)
|
self._timeout = ClientTimeout(total=total_timeout)
|
||||||
self._session = None
|
self._session = None
|
||||||
self._connector_force_close = True
|
|
||||||
|
|
||||||
async def _get_session(self) -> ClientSession:
|
async def _get_session(self) -> ClientSession:
|
||||||
if self._session is None or self._session.closed:
|
if self._session is None or self._session.closed:
|
||||||
connector = TCPConnector(force_close=self._connector_force_close)
|
|
||||||
self._session = ClientSession(
|
self._session = ClientSession(
|
||||||
timeout=self._timeout,
|
timeout=self._timeout,
|
||||||
connector=connector,
|
|
||||||
headers={"User-Agent": _PAYMENT_REQUEST_USER_AGENT},
|
|
||||||
trace_configs=[_payment_trace_config()],
|
trace_configs=[_payment_trace_config()],
|
||||||
)
|
)
|
||||||
return self._session
|
return self._session
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import unittest
|
|||||||
|
|
||||||
from bot.payment_providers.shared.http_client import (
|
from bot.payment_providers.shared.http_client import (
|
||||||
HttpClientMixin,
|
HttpClientMixin,
|
||||||
_PAYMENT_REQUEST_USER_AGENT,
|
|
||||||
_should_retry_transport_error,
|
_should_retry_transport_error,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,13 +12,12 @@ class _DummyHttpClient(HttpClientMixin):
|
|||||||
|
|
||||||
|
|
||||||
class PaymentHttpClientTests(unittest.IsolatedAsyncioTestCase):
|
class PaymentHttpClientTests(unittest.IsolatedAsyncioTestCase):
|
||||||
async def test_http_client_does_not_reuse_provider_tcp_connections(self):
|
async def test_http_client_tracks_sent_headers_for_safe_retries(self):
|
||||||
client = _DummyHttpClient()
|
client = _DummyHttpClient()
|
||||||
try:
|
try:
|
||||||
session = await client._get_session()
|
session = await client._get_session()
|
||||||
self.assertTrue(session.connector.force_close)
|
self.assertFalse(session.connector.force_close)
|
||||||
self.assertTrue(session.trace_configs)
|
self.assertTrue(session.trace_configs)
|
||||||
self.assertEqual(session.headers["User-Agent"], _PAYMENT_REQUEST_USER_AGENT)
|
|
||||||
finally:
|
finally:
|
||||||
await client.close()
|
await client.close()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user