Process a batch of requests with automatic retry mechanism. Returns: A response aggregating all requests processed across attempts plus any still unprocessed once the retries are exhausted.
(
self,
batch: Sequence[Request],
*,
base_retry_wait: timedelta,
attempt: int = 1,
forefront: bool = False,
)
| 345 | return False |
| 346 | |
| 347 | async def _process_batch( |
| 348 | self, |
| 349 | batch: Sequence[Request], |
| 350 | *, |
| 351 | base_retry_wait: timedelta, |
| 352 | attempt: int = 1, |
| 353 | forefront: bool = False, |
| 354 | ) -> AddRequestsResponse: |
| 355 | """Process a batch of requests with automatic retry mechanism. |
| 356 | |
| 357 | Returns: |
| 358 | A response aggregating all requests processed across attempts plus any still unprocessed once the |
| 359 | retries are exhausted. |
| 360 | """ |
| 361 | max_attempts = 5 |
| 362 | response = await self._client.add_batch_of_requests(batch, forefront=forefront) |
| 363 | |
| 364 | request_count = len(batch) - len(response.unprocessed_requests) |
| 365 | if request_count: |
| 366 | logger.debug( |
| 367 | f'Added {request_count} requests to the queue. Processed requests: {response.processed_requests}' |
| 368 | ) |
| 369 | |
| 370 | if not response.unprocessed_requests: |
| 371 | return response |
| 372 | |
| 373 | logger.debug(f'Following requests were not processed: {response.unprocessed_requests}.') |
| 374 | if attempt > max_attempts: |
| 375 | logger.warning( |
| 376 | f'Following requests were not processed even after {max_attempts} attempts:\n' |
| 377 | f'{response.unprocessed_requests}' |
| 378 | ) |
| 379 | return response |
| 380 | |
| 381 | logger.debug('Retry to add requests.') |
| 382 | unprocessed_requests_unique_keys = {request.unique_key for request in response.unprocessed_requests} |
| 383 | retry_batch = [request for request in batch if request.unique_key in unprocessed_requests_unique_keys] |
| 384 | await asyncio.sleep((base_retry_wait * attempt).total_seconds()) |
| 385 | retry_response = await self._process_batch( |
| 386 | retry_batch, |
| 387 | base_retry_wait=base_retry_wait, |
| 388 | attempt=attempt + 1, |
| 389 | forefront=forefront, |
| 390 | ) |
| 391 | |
| 392 | # Merge the retry outcome: processed requests accumulate, unprocessed is whatever the last attempt left. |
| 393 | return AddRequestsResponse( |
| 394 | processed_requests=[*response.processed_requests, *retry_response.processed_requests], |
| 395 | unprocessed_requests=retry_response.unprocessed_requests, |
| 396 | ) |
no test coverage detected