Skip to content

Commit 8b9b013

Browse files
committed
adding a sleep cycle
1 parent e612ed2 commit 8b9b013

2 files changed

Lines changed: 47 additions & 18 deletions

File tree

imap_processing/cli.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import sys
1919
from abc import ABC, abstractmethod
2020
from pathlib import Path
21+
from time import sleep
2122
from typing import final
2223

2324
import imap_data_access
@@ -472,6 +473,8 @@ def upload_products(self, products: list[Path]) -> None:
472473
"""
473474
Upload data products to the IMAP SDC.
474475
476+
If a 503 SlowDown error is reported from the Upload API, a retry will be made
477+
475478
Parameters
476479
----------
477480
products : list[Path]
@@ -483,19 +486,36 @@ def upload_products(self, products: list[Path]) -> None:
483486
return
484487

485488
for filename in products:
486-
try:
487-
logger.info(f"Uploading file: {filename}")
488-
imap_data_access.upload(filename)
489-
except IMAPDataAccessError as e:
490-
message = str(e)
491-
if "FileAlreadyExists" in message and "409" in message:
492-
logger.warning("Skipping upload of existing file, %s", filename)
493-
continue
494-
else:
489+
max_retries = 3
490+
491+
for attempt in range(max_retries):
492+
try:
493+
logger.info(f"Uploading file: {filename}")
494+
imap_data_access.upload(filename)
495+
break
496+
497+
except IMAPDataAccessError as e:
498+
message = str(e)
499+
500+
if "FileAlreadyExists" in message and "409" in message:
501+
logger.warning(
502+
"Skipping upload of existing file, %s", filename
503+
)
504+
break
505+
elif "503" in message and "SlowDown" in message:
506+
if attempt < max_retries - 1:
507+
logger.warning(
508+
"Upload busy. Waiting 5 seconds before retrying..."
509+
)
510+
sleep(5)
511+
continue
512+
495513
logger.error(f"Upload failed with error: {message}")
496514
raise
497-
except Exception as e:
498-
logger.error(f"Upload failed unknown error: {e}")
515+
516+
except Exception as e:
517+
logger.error(f"Upload failed unknown error: {e}")
518+
raise
499519

500520
@final
501521
def process(self) -> None:

imap_processing/tests/test_cli.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -939,11 +939,13 @@ def test_post_processing(
939939
]
940940

941941

942+
@mock.patch("imap_processing.cli.sleep")
942943
@mock.patch("imap_processing.cli.filter_day_boundary_data")
943944
@mock.patch("imap_processing.cli.swe_l1a")
944945
def test_post_processing_upload_503_error(
945946
mock_swe_l1a,
946947
mock_filter,
948+
mock_sleep,
947949
mock_instrument_dependencies,
948950
):
949951
"""Test coverage for post processing when the upload fails with 503 error"""
@@ -960,8 +962,10 @@ def test_post_processing_upload_503_error(
960962

961963
# Mocks a 503 error received from the upload API
962964
mocks["mock_upload"].side_effect = imap_data_access.io.IMAPDataAccessError(
963-
'503 Service Unavailable: {"error": "ServiceUnavailable", '
964-
'"message": "The API is too busy."}'
965+
"503 Service Unavailable: "
966+
"<title>503 Slow Down</title>"
967+
"Code: SlowDown"
968+
"Message: Please reduce your request rate."
965969
)
966970

967971
test_ds = xr.Dataset()
@@ -984,8 +988,13 @@ def test_post_processing_upload_503_error(
984988
with pytest.raises(imap_data_access.io.IMAPDataAccessError):
985989
instrument.process()
986990

987-
# Checks the upload failure was logged
988-
assert any(
989-
"Upload failed with error" in str(call)
990-
for call in mock_error.call_args_list
991-
)
991+
# Upload should attempt 3 times
992+
assert mocks["mock_upload"].call_count == 3
993+
994+
# Sleep should be called 2 times after first two failures
995+
assert mock_sleep.call_count == 2
996+
997+
# Checks the upload failure was logged
998+
assert any(
999+
"Upload failed with error" in str(call) for call in mock_error.call_args_list
1000+
)

0 commit comments

Comments
 (0)