Skip to content
Draft
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
1 change: 1 addition & 0 deletions CHANGES/7846.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix temp file leak in pull-through metadata streaming.
7 changes: 4 additions & 3 deletions pulpcore/content/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,7 @@ async def _match_and_stream(self, path, request):
# Try to stream the RemoteArtifact and potentially save it as a new Content unit
save_artifact = (
remote.get_remote_artifact_content_type(original_rel_path) is not None
and remote.policy != Remote.STREAMED
)
ca = ContentArtifact(relative_path=original_rel_path)
ra = RemoteArtifact(remote=remote, url=url, content_artifact=ca)
Expand Down Expand Up @@ -1289,12 +1290,12 @@ async def handle_data(data):
data_size_handled = data_size_handled + len(data)
else:
await response.write(data)
if remote.policy != Remote.STREAMED:
if save_artifact:
await original_handle_data(data)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the downloader saves the file to disk?
At the very least this change looks reasonable to me.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there are several places where we check for exactly save_artifact and remote.policy != Remote.STREAMED can we redefine the variable so that it already contains the streamed condition?

(Somehow this may be a copy-and-paste / missed-all-the-places-to-update bug coming from exactly there.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where the downloader saves the file to disk?

Yes, original_handle_data that usually points to BasedDownloader handle_data that does the writing (if not overriden by plugins downloader)


async def finalize():
nonlocal failed_download
if save_artifact and remote.policy != Remote.STREAMED:
if save_artifact:
await original_finalize()
failed_download = False

Expand Down Expand Up @@ -1342,7 +1343,7 @@ async def finalize():
if hasattr(downloader, "session"):
await downloader.session.close()

if save_artifact and remote.policy != Remote.STREAMED:
if save_artifact:
content_artifacts = await asyncio.shield(
sync_to_async(self._save_artifact)(download_result, remote_artifact, request)
)
Expand Down
Loading