55from pydantic import BaseModel
66
77from ..error import AutumnError , AutumnHTTPError
8- from ..http import HTTPClient
9- from ..utils import _build_model , _check_response
8+ from ..http import HTTPClient , _RetryRequestError
9+ from ..utils import _build_model , _check_response , ExponentialBackoff
1010
1111
1212try :
2323__all__ = ("AsyncHTTPClient" ,)
2424
2525
26- class _RetryRequestError (Exception ):
27- pass
28-
29-
3026class AsyncHTTPClient :
3127 def __init__ (
3228 self ,
3329 base_url : str ,
3430 version : str ,
3531 token : str ,
36- max_retries : int = 3 ,
32+ attempts : int ,
3733 * ,
3834 session : Optional [aiohttp .ClientSession ] = None
3935 ):
4036 self .base_url = base_url
4137 self .version = version
4238 self .session = session # type: ignore
4339 self ._headers = HTTPClient ._build_headers (token )
44- self .max_retries = max_retries
40+ self .attempts = attempts
4541
4642 self ._build_url = HTTPClient ._build_url
4743
48- rand = random .Random ()
49- rand .seed ()
50- self ._rand = rand
51-
5244 async def request (self , method : str , path : str , type_ : Type [T ], ** kwargs ) -> T :
5345 if self .session is None :
5446 self .session = aiohttp .ClientSession ()
5547
5648 url = self ._build_url (self .base_url , self .version , path )
5749
58- for attempt in range (self .max_retries ):
50+ max_attempts = self .attempts
51+ backoff = ExponentialBackoff ()
52+ for attempt in range (max_attempts ):
5953 try :
6054 async with self .session .request (
6155 method , url , headers = self ._headers , ** kwargs
@@ -66,12 +60,16 @@ async def request(self, method: str, path: str, type_: Type[T], **kwargs) -> T:
6660 data = await resp .json ()
6761
6862 except (_RetryRequestError , OSError , asyncio .TimeoutError ):
69- sleep_time = (2 ** attempt ) + self ._rand .uniform (0 , 1 )
70- await asyncio .sleep (sleep_time )
63+ if attempt == max_attempts - 1 :
64+ raise
65+
66+ await asyncio .sleep (backoff .bedtime )
67+ backoff .tick ()
7168 else :
7269 _check_response (resp .status , data )
7370 return _build_model (type_ , data )
74-
71+
72+ # We should never get here. This is to appease type checkers.
7573 msg = f"Max retries reached for { method } { path } "
7674 raise AutumnHTTPError (msg , "max_retries_reached" , 500 )
7775
0 commit comments