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

Fix import URL eating tons of memory on large file downloads #5826

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

nirvn
Copy link
Member

@nirvn nirvn commented Nov 17, 2024

This PR introduces the use of a temporary file to progressively save data as a file is being downloaded during the import URL process.

This should prevent QField from crashed caused by running out of memory when downloading large files in this process.

@qfield-fairy
Copy link
Collaborator

qfield-fairy commented Nov 17, 2024

src/core/appinterface.cpp Outdated Show resolved Hide resolved
@m-kuhn
Copy link
Member

m-kuhn commented Nov 17, 2024

good move

Copy link
Collaborator

@suricactus suricactus left a comment

Choose a reason for hiding this comment

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

Good! We need to double check whether the QFC integration does the same.

@@ -286,15 +296,18 @@ void AppInterface::importUrl( const QString &url )

QNetworkReply *reply = manager->get( request );
connect( reply, &QNetworkReply::downloadProgress, this, [=]( int bytesReceived, int bytesTotal ) {
temporaryFile->write( reply->readAll() );
if ( bytesTotal != 0 )
{
emit importProgress( static_cast<double>( bytesReceived ) / bytesTotal );
}
} );

connect( reply, &QNetworkReply::finished, this, [=]() {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
connect( reply, &QNetworkReply::finished, this, [=]() {
std::unique_ptr<QTemporaryFile> temporaryFile = std::make_unique<QTemporaryFile>();
connect( reply, &QNetworkReply::finished, tmpFile = std::move( temporaryFile ), this, [=]() {

I don't see it bringing many real advantages, but it would be a tiny bit cleaner ... does that work?

Copy link
Member Author

Choose a reason for hiding this comment

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

That would scope out at the end of the importUrl function and kill the object no?

Copy link
Member

@m-kuhn m-kuhn Nov 18, 2024

Choose a reason for hiding this comment

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

There can only be one unique_ptr wich is moved into the lambda.
The lambda lifetime is bound to the connection.
The connection lifetime is bound to the lifetime of reply and this.
But I admit my understanding of this is not 100% water proof.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants