@@ -65,6 +65,9 @@ def __init__(
6565 super ().__init__ (endpoint_uri = URI (endpoint_urls [0 ]))
6666
6767 async def make_request (self , method : RPCEndpoint , params : Any ) -> RPCResponse :
68+ """
69+ Request with retries and fallback endpoints.
70+ """
6871 if self .retry_timeout :
6972
7073 def custom_before_log (retry_state : 'RetryCallState' ) -> None :
@@ -78,11 +81,13 @@ def custom_before_log(retry_state: 'RetryCallState') -> None:
7881 self .retry_timeout ,
7982 before = custom_before_log ,
8083 )
81- return await retry_decorator (self .make_request_inner )(method , params )
84+ return await retry_decorator (self .make_request_with_fallback_endpoints )(method , params )
8285
83- return await self .make_request_inner (method , params )
86+ return await self .make_request_with_fallback_endpoints (method , params )
8487
85- async def make_request_inner (self , method : RPCEndpoint , params : Any ) -> RPCResponse :
88+ async def make_request_with_fallback_endpoints (
89+ self , method : RPCEndpoint , params : Any
90+ ) -> RPCResponse :
8691 for i , provider in enumerate (self ._providers ):
8792 is_last_iteration = i == len (self ._providers ) - 1
8893 try :
@@ -106,6 +111,51 @@ async def make_request_inner(self, method: RPCEndpoint, params: Any) -> RPCRespo
106111
107112 return {}
108113
114+ async def make_batch_request (
115+ self , batch_requests : list [tuple [RPCEndpoint , Any ]]
116+ ) -> list [RPCResponse ] | RPCResponse :
117+ """
118+ Batch request with retries and fallback endpoints.
119+ """
120+ if self .retry_timeout :
121+
122+ def custom_before_log (retry_state : 'RetryCallState' ) -> None :
123+ if retry_state .attempt_number <= 1 :
124+ return
125+ msg = 'Retrying execution batch request, attempt %s'
126+ args = (retry_state .attempt_number ,)
127+ logger .log (logging .INFO , msg , * args )
128+
129+ retry_decorator = retry_aiohttp_errors (
130+ self .retry_timeout ,
131+ before = custom_before_log ,
132+ )
133+ return await retry_decorator (self .make_batch_request_with_fallback_endpoints )(
134+ batch_requests
135+ )
136+
137+ return await self .make_batch_request_with_fallback_endpoints (batch_requests )
138+
139+ async def make_batch_request_with_fallback_endpoints (
140+ self , batch_requests : list [tuple [RPCEndpoint , Any ]]
141+ ) -> list [RPCResponse ] | RPCResponse :
142+ for i , provider in enumerate (self ._providers ):
143+ is_last_iteration = i == len (self ._providers ) - 1
144+ try :
145+ response = await provider .make_batch_request (batch_requests )
146+ # No special error handling for batch, just fallback on exception
147+ return response
148+ except Exception as error :
149+ if not can_be_retried_aiohttp_error (error ):
150+ raise error
151+
152+ if is_last_iteration :
153+ raise error
154+
155+ logger .warning ('%s: %s' , provider .endpoint_uri , repr (error ))
156+
157+ return []
158+
109159 def set_retry_timeout (self , retry_timeout : int ) -> None :
110160 self .retry_timeout = retry_timeout
111161
0 commit comments