2727s3_router = APIRouter (prefix = "/s3" )
2828
2929
30- s3_max_retries = 3
31- s3_retry_base_delay = 0.5
32- s3_retry_backoff_factor = 2
30+ S3_MAX_RETRIES = 3
31+ S3_RETRY_BASE_DELAY = 0.5
32+ S3_RETRY_BACKOFF_FACTOR = 2
3333
3434
3535async def set_access_token_and_get_user_id (auth : Auth , headers : Headers ) -> str :
@@ -351,8 +351,7 @@ async def s3_endpoint(path: str, request: Request):
351351
352352 # forward the call to AWS S3 with the new Authorization header.
353353 # this call is retried with exponential backoff in case of unexpected error from S3.
354- attempt = 1
355- while True :
354+ for attempt in range (1 , S3_MAX_RETRIES + 1 ):
356355 proceed = True
357356 exception = None
358357 try :
@@ -367,7 +366,7 @@ async def s3_endpoint(path: str, request: Request):
367366 if response .status_code >= 300 :
368367 # no need to log details (unless in debug mode) or retry in the case of a 404
369368 # error: 404s are are expected when running workflows (e.g. for Nextflow workflows,
370- # error output files may not be present when there were no errors)
369+ # stderr output files may not be present when there were no errors)
371370 if response .status_code != HTTP_404_NOT_FOUND :
372371 logger .error (
373372 f"Error from S3: { response .status_code } { response .text } "
@@ -387,22 +386,21 @@ async def s3_endpoint(path: str, request: Request):
387386 # retries
388387 if proceed :
389388 break
390- if attempt == s3_max_retries :
389+ if attempt == S3_MAX_RETRIES :
391390 logger .error (
392- f"Outgoing S3 request failed (attempt { attempt } /{ s3_max_retries } ). Giving up"
391+ f"Outgoing S3 request failed (attempt { attempt } /{ S3_MAX_RETRIES } ). Giving up"
393392 )
394393 if exception :
395394 raise exception
396395 break
397396
398397 # retry with exponential backoff
399- delay = s3_retry_base_delay * (s3_retry_backoff_factor ** attempt )
398+ delay = S3_RETRY_BASE_DELAY * (S3_RETRY_BACKOFF_FACTOR ** attempt )
400399 delay += delay * 0.1 * random .uniform (- 1 , 1 ) # add jitter
401400 logger .warning (
402- f"Outgoing S3 request failed (attempt { attempt } /{ s3_max_retries } ). Retrying in { delay :.2f} seconds"
401+ f"Outgoing S3 request failed (attempt { attempt } /{ S3_MAX_RETRIES } ). Retrying in { delay :.2f} seconds"
403402 )
404403 await asyncio .sleep (delay )
405- attempt += 1
406404
407405 # return the response from AWS S3.
408406 # - mask the details of 403 errors from the end user: authentication is done internally by this
0 commit comments