Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retry celery patron sync on StaleDataError (PP-2005) #2207

Merged
merged 2 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/palace/manager/celery/tasks/patron_activity.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from celery import shared_task
from sqlalchemy.orm.exc import StaleDataError

from palace.manager.api.circulation import PatronActivityCirculationAPI
from palace.manager.api.circulation_exceptions import PatronAuthorizationFailedException
Expand Down Expand Up @@ -80,8 +81,9 @@ def sync_patron_activity(
"Marking patron activity as failed."
)
return
except RemoteIntegrationException as e:
# This may have been a transient network error with the remote integration. Attempt to retry.
except (RemoteIntegrationException, StaleDataError) as e:
# This may have been a transient network error with the remote integration or some data
# changed while we were processing the sync. Attempt to retry.
retries = task.request.retries
if retries < task.max_retries:
wait_time = exponential_backoff(retries)
Expand Down
16 changes: 14 additions & 2 deletions tests/manager/celery/tasks/test_patron_activity.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from unittest.mock import MagicMock, create_autospec, patch

import pytest
from sqlalchemy.orm.exc import StaleDataError

from palace.manager.api.circulation import HoldInfo, LoanInfo
from palace.manager.api.circulation_exceptions import PatronAuthorizationFailedException
Expand Down Expand Up @@ -150,9 +151,20 @@ def test_patron_authorization_failed_exception(
)

@patch("palace.manager.celery.tasks.patron_activity.exponential_backoff")
def test_remote_integration_exception(
@pytest.mark.parametrize(
"exception",
[
pytest.param(StaleDataError(), id="StaleDataError"),
pytest.param(
RemoteIntegrationException("http://test.com", "boom!"),
id="RemoteIntegrationException",
),
],
)
def test_retried_exception(
self,
mock_backoff: MagicMock,
exception: Exception,
sync_task_fixture: SyncTaskFixture,
caplog: pytest.LogCaptureFixture,
):
Expand All @@ -161,7 +173,7 @@ def test_remote_integration_exception(

mock_activity = create_autospec(
sync_task_fixture.mock_collection_api.patron_activity,
side_effect=RemoteIntegrationException("http://test.com", "boom!"),
side_effect=exception,
)
sync_task_fixture.mock_collection_api.patron_activity = mock_activity

Expand Down
Loading