Skip to content

Commit

Permalink
Add ClientConnectionError as retriable exception on content-app strea…
Browse files Browse the repository at this point in the history
…ming

A user reported that after changing the host and resyncing they
would have some some leftover RAs with the invalid url, and that would
raise an aiohttp.client_exceptions.ClientConnectionError.

Because that is not a retriable error for content streaming,
the right RA wouldnt be tried afterwards.

Fixes #5967

(cherry picked from commit 9b5d907)
  • Loading branch information
pedro-psb authored and patchback[bot] committed Nov 12, 2024
1 parent fe309a9 commit 6d2e171
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGES/5967.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
On the content-app, added ClientConnectionError (aiohttp) as an exception that can trigger
a retry when streaming content from a Remote.
12 changes: 9 additions & 3 deletions pulpcore/content/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import re
from gettext import gettext as _

from aiohttp.client_exceptions import ClientResponseError
from aiohttp.client_exceptions import ClientResponseError, ClientConnectionError
from aiohttp.web import FileResponse, StreamResponse, HTTPOk
from aiohttp.web_exceptions import (
HTTPError,
Expand Down Expand Up @@ -756,6 +756,13 @@ async def _stream_content_artifact(self, request, response, content_artifact):
:class:`~pulpcore.plugin.models.ContentArtifact` returned the binary data needed for
the client.
"""
# We should only retry with exceptions that happen before we receive any data
# and start streaming, as we can't rollback data if something happens after that.
RETRYABLE_EXCEPTIONS = (
ClientResponseError,
UnsupportedDigestValidationError,
ClientConnectionError,
)

remote_artifacts = content_artifact.remoteartifact_set.select_related(
"remote"
Expand All @@ -764,8 +771,7 @@ async def _stream_content_artifact(self, request, response, content_artifact):
try:
response = await self._stream_remote_artifact(request, response, remote_artifact)
return response

except (ClientResponseError, UnsupportedDigestValidationError) as e:
except RETRYABLE_EXCEPTIONS as e:
log.warning(
"Could not download remote artifact at '{}': {}".format(
remote_artifact.url, str(e)
Expand Down

0 comments on commit 6d2e171

Please sign in to comment.