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

Pause session till all torrents are fully started #9007

Closed

Conversation

sledgehammer999
Copy link
Member

There were many user reports that complained that qbt started downloading over their data when they had forgotten to plugin the drive the torrents were in. Or forgotten to mount the partition/share etc.

I was confused because I personally had implemented a measure against this. I was even more confused because I couldn't reproduce it. Until some days ago. After a lot of trial and error it turns out that during startup libtorrent produces a ton of alerts. A lot more than 1000 at a time. And these alerts ended up throwing out of the queue the fastresume_rejected_alert alerts, thus my counter measure was never activated. A longer discussion here: arvidn/libtorrent#3045

Naturally as I had delved into this I discovered other inefficiencies. There's a timing issue where the torrent might start downloading and writing data to disk before we have the chance to pause it.
I opted to have the session paused untill all torrents were loaded and handled.

To my experience, the 3 alerts that interest us are received in this order:
add_torrent_alert -> fastresume_rejected_alert -> torrent_added_alert

About the "Temp solution" commit. This is temporary fix in order to publish the PR and have feedback from you. Relevant bug report: arvidn/libtorrent#3071

IMO, it's better to see each commit by itself.

Caveats:

  1. I didn't thoroughly test the PR. Please help by doing runs yourselves too.
  2. The RC_1_0 code path wasn't even tested if it compiles. I will do it as final step before merge.

@wesleybl
Copy link

@sledgehammer999 if I remove the disk where the torrent was downloaded and start the qbittorrent what will happen with the percentage completed? Will keep 100% but will indicate error?

@glassez
Copy link
Member

glassez commented May 30, 2018

@sledgehammer999, well, great job!
Although, it requires more changes.

  1. We need to return the correct components loading sequence (startupTorrents should again become a part of the initialization of the session, and not be called from outside).
  2. Torrent-manipulation actions (e.g. add torrent, delete torrent) should be unavailable (or maybe queued) until session is fully initialized (i.e. resumed all torrents).
  3. We no need more two signals (torrentAdded/torrentNew) since it will indicate the same event.
  4. Some GUI components should be disabled until session is fully initialized (or unavailable in some other way, e.g. we can show no GUI or show progress dialog).

@@ -181,6 +181,12 @@ CategoryFilterModel::CategoryFilterModel(QObject *parent)
connect(session, &Session::categoryRemoved, this, &CategoryFilterModel::categoryRemoved);
connect(session, &Session::torrentCategoryChanged, this, &CategoryFilterModel::torrentCategoryChanged);
connect(session, &Session::subcategoriesSupportChanged, this, &CategoryFilterModel::subcategoriesSupportChanged);
connect(session, &Session::finishedStartingUp, this,
[this, session]()
Copy link
Member

Choose a reason for hiding this comment

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

I would move it on the previous line in all similar cases of this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Do you mean the lambda? Have it as a one liner?

Copy link
Member Author

Choose a reason for hiding this comment

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

On 2nd thought, you probably mean only the capture clause and parameter list.

Copy link
Member

Choose a reason for hiding this comment

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

On 2nd thought, you probably mean only the capture clause and parameter list.

Yes.

@@ -3808,11 +3786,14 @@ void Session::startUpTorrents()
QByteArray data;
} TorrentResumeData;

m_nativeSession->pause();
Copy link
Member

Choose a reason for hiding this comment

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

It would be better if we can create session in paused state.

@@ -4009,6 +3990,12 @@ void Session::handleAlert(libt::alert *a)
case libt::add_torrent_alert::alert_type:
handleAddTorrentAlert(static_cast<libt::add_torrent_alert*>(a));
break;
case libt::torrent_added_alert::alert_type:
if (m_startupInProgress)
Copy link
Member

Choose a reason for hiding this comment

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

Please don't break the current style. Just add handleTorrentAddedAlert() method.

if (m_startupInProgress)
--m_startedCount;
if (m_startedCount == 0 && m_startupInProgress)
handleStartUpFinish();
Copy link
Member

Choose a reason for hiding this comment

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

handleStartUpFinished

@@ -538,6 +538,7 @@ namespace BitTorrent
void subcategoriesSupportChanged();
void tagAdded(const QString &tag);
void tagRemoved(const QString &tag);
void finishedStartingUp();
Copy link
Member

Choose a reason for hiding this comment

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

startupFinished

connect(session, &Session::finishedStartingUp, this,
[this, session]()
{
for (const auto &handle : session->torrents().values())
Copy link
Member

Choose a reason for hiding this comment

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

add qAsConst()?
or use iterator to loop, this avoids redundant traverse over the container, although I like the use of values() :P

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure. I am still confused about those macros. Eventually I'll get the hang of them.

@Chocobo1
Copy link
Member

Torrent-manipulation actions (e.g. add torrent, delete torrent) should be unavailable (or maybe queued) until session is fully initialized (i.e. resumed all torrents).

I agree with the idea, making it unavailable seems simpler.

Some GUI components should be disabled until session is fully initialized (or unavailable in some other way, e.g. we can show no GUI or show progress dialog).

Since this is an interactive program, displaying no GUI would be a bad choice.
If feasible, I would choose to ready the mainwindow as early as possible (modern browsers startup time is impressive!) and let user know program is still initializing: could be some text in statusbar, or display the torrent jobs initially as "not yet loaded" and transition to other ready state (paused or downloading) when it is loaded.

@glassez
Copy link
Member

glassez commented May 30, 2018

or display the torrent jobs initially as "not yet loaded" and transition to other ready state (paused or downloading) when it is loaded.

Session doesn't emit signals for resumed torrents in changed code, only one startupFinished signal, and I really like this idea.

@glassez
Copy link
Member

glassez commented May 30, 2018

I agree with the idea, making it unavailable seems simpler.

We still need queuing at least for "add torrent" action since the application can start with torrents specified in command line. Of course, we can implement it outside the Session.

@sledgehammer999
Copy link
Member Author

I addressed some of the comments in my 3rd commit

I pushed 2 new commits. Now the initial loading of the torrents is done in a separate thread. However, for me, the mainwindow still takes quite a few seconds to draw its contents. The initial blank/white window is drawn quickly. The widgets are taking quite a few seconds.
The 2 new commits were written rather hastily with not enough testing. So rip them apart in the review.

@Chocobo1
Copy link
Member

Now the initial loading of the torrents is done in a separate thread. However, for me, the mainwindow still takes quite a few seconds to draw its contents.

Haven't tried this PR yet, (for you) does it still take seconds to draw the GUI even when there are no torrents?

@wesleybl
Copy link

@sledgehammer999 I would like to test this PR in Windows. If I do:

./configure
make && make install
qbittorrent

on Linux and copying the files to Windows will work?

@glassez
Copy link
Member

glassez commented Aug 11, 2018

@sledgehammer999, unfortunately I can't say that I approve this PR in its current form. It's more like a rough workaround (in terms of its design).
However, as I see it, it takes away from you the resources that are already missing for full maintainence of the project. So you are free to merge it if you think its purpose is achieved (from a user point of view, closing our eyes to its implementation) in the hope that we will polish and improve it in the future.
But I would make upcoming release ASAP (without this PR) and then merge it immediately so we would be able to test it thoroughly and fix/improve it before the next release.

P.S. Have you ever thought of having an additional release manager? This could help to make releases on time. It is a very hateful situation, when hotfixes "rot" in the master for several months while the bugtracker is filled with duplicate issues!

@ghost
Copy link

ghost commented Sep 1, 2018

I have this problem too. Looks like add_torrent with flag_override_resume_data can help solve this problem.

@sledgehammer999 sledgehammer999 modified the milestones: 4.1.3, 4.1.4 Sep 18, 2018
@thalieht thalieht mentioned this pull request Sep 19, 2018
@sledgehammer999 sledgehammer999 modified the milestones: 4.1.4, 4.1.5 Nov 19, 2018
@sledgehammer999 sledgehammer999 modified the milestones: 4.1.5, 4.1.6 Dec 24, 2018
@glassez
Copy link
Member

glassez commented Dec 29, 2018

@sledgehammer999, you still want to do something about it?

@glassez
Copy link
Member

glassez commented Aug 7, 2019

@githubuserthatsright
Copy link

Just so that I understand - this potential fix, or for that matter maybe any other, has been around for a bit over a year and more than just a few version updates and we've still got this as a problem?

@glassez
Copy link
Member

glassez commented Aug 12, 2019

Just so that I understand - this potential fix, or for that matter maybe any other, has been around for a bit over a year and more than just a few version updates and we've still got this as a problem?

The problems it was supposed to solve (at least most of them) are now solved in a different way.

@githubuserthatsright
Copy link

So moving or deleting data of a formerly completed torrrent will in no case any longer cause a redownload?

@glassez
Copy link
Member

glassez commented Aug 12, 2019

So moving or deleting data of a formerly completed torrrent will in no case any longer cause a redownload?

This should be fixed now.

@sledgehammer999 sledgehammer999 modified the milestones: 4.1.8, 4.1.10 Oct 27, 2019
@glassez
Copy link
Member

glassez commented Jun 3, 2020

The goal was achieved in a different way.

@glassez glassez closed this Jun 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants