Merge lp:~mandel/ubuntu-download-manager/network-errors-management into lp:ubuntu-download-manager

Proposed by Manuel de la Peña
Status: Merged
Approved by: Manuel de la Peña
Approved revision: 135
Merged at revision: 131
Proposed branch: lp:~mandel/ubuntu-download-manager/network-errors-management
Merge into: lp:ubuntu-download-manager
Prerequisite: lp:~mandel/ubuntu-download-manager/smart-ignore-sslerrors
Diff against target: 128 lines (+10/-15)
3 files modified
libubuntudownloadmanager/download_queue.cpp (+1/-1)
libubuntudownloadmanager/group_download.cpp (+7/-14)
ubuntu-download-manager-tests/test_group_download.cpp (+2/-0)
To merge this branch: bzr merge lp:~mandel/ubuntu-download-manager/network-errors-management
Reviewer Review Type Date Requested Status
Mike McCracken (community) Approve
PS Jenkins bot continuous-integration Approve
Diego Sarmentero (community) Approve
Review via email: mp+186739@code.launchpad.net

Commit message

Ensure that when there is a network error the state of the GroupDownload is correctly set.

Description of the change

Ensure that when there is a network error the state of the GroupDownload is correctly set.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
132. By Manuel de la Peña

Do no use the DownloadQueue object for GroupDownloads so that segfault is fixes and downloads are done in parallel.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

looks good

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Manuel de la Peña (mandel) wrote :

Please allow me to do the global approve, when this branch lands on trunk is very important due to deployment details.

Revision history for this message
Mike McCracken (mikemc) wrote :

This MP and its description is confusing me:

I see the change from 'emit q->error(errorMsg)' to 'q->emitError(errorMsg)', which will correctly set the state to ERROR in onError, but there are a bunch of other changes that you haven't described and I can't tell from the linked bugs what's going on:

1. What was causing the segfault bug, and which changes in here fixed it?
1a. Is it possible to add a test that triggers that bug? The tests added seem to just be about the ERROR state.

2. Is the change in cancelDownload() and pauseDownload() from a reverse loop to a regular foreach significant?

On an API style note - It took a while to understand why you had pairs of methods like cancel() and cancelDownload() - I guess it was because the DownloadQueue listens for the state change caused by cancel(), and then calls cancelDownload() itself. That seems like cancel() should be called something like setState(CANCELLED) or something like that, because 'download->cancelDownload()' is awkward - that should be 'download->cancel()', because it's actually doing the cancelling.

It was also strange to me that the object can be in the "cancelled" (or "paused" or whatever) state, while not actually having been cancelled yet. So for each of these states, there's two states - "about to be <state>" and "really <state>". This seems like it might be a source of problems, and was definitely a source of confusion while reading. Anyway, probably not worth messing with here, but I thought I'd mention it.

review: Needs Information
Revision history for this message
Mike McCracken (mikemc) wrote :

Also, my usual grumpy complaint that even though it's short, this still seems like at least two independent branches worth of changes. The error state fix is trivially reviewable, but the other part is delaying it.

Revision history for this message
Manuel de la Peña (mandel) wrote :
Download full text (3.5 KiB)

> This MP and its description is confusing me:
>
> I see the change from 'emit q->error(errorMsg)' to 'q->emitError(errorMsg)',
> which will correctly set the state to ERROR in onError, but there are a bunch
> of other changes that you haven't described and I can't tell from the linked
> bugs what's going on:
>
> 1. What was causing the segfault bug, and which changes in here fixed it?
> 1a. Is it possible to add a test that triggers that bug? The tests added seem
> to just be about the ERROR state.
>

The segafault was caused because the DownloadQueue calls deleteLater when a Download is completed or canceled, once that is done the pointer in the _downloads array in the GroupDownload is pointer to unknown memory space and we go banannas due to that. I really cannot think of a good way to test that error specially now that the q is not longer present.

> 2. Is the change in cancelDownload() and pauseDownload() from a reverse loop
> to a regular foreach significant?
>

At the very beginning (with the use of the DownloadQueue) it was a good idea to do it in reverse order because it minimized the number of operations to be performed in the q, mainlye because the downloads being paused/canceled are not the 'current download'. With the q implementation if you paused from first to last the download q will attempt to recalculate the next download to be performed something that really is not required in a group. Once the Download Queue was out there was no need to be careful with the order.

>
> On an API style note - It took a while to understand why you had pairs of
> methods like cancel() and cancelDownload() - I guess it was because the
> DownloadQueue listens for the state change caused by cancel(), and then calls
> cancelDownload() itself. That seems like cancel() should be called something
> like setState(CANCELLED) or something like that, because
> 'download->cancelDownload()' is awkward - that should be 'download->cancel()',
> because it's actually doing the cancelling.

Yes, I agree that it is a funny way to do it, the main issue is that the cancel, start, etc.. methods are exposed by the DownloadAdapetor that does something of the following:

QMetaObject::invokeMethod(parent(), "cancel");

As you can see, if you use the adaptors generated by the qt tool you need to call the methods the same way as those found in the interface... I might move away from the xml-generated classes but I need to consider if that is a source of problems later in the future if we change the xml.

>
> It was also strange to me that the object can be in the "cancelled" (or
> "paused" or whatever) state, while not actually having been cancelled yet. So
> for each of these states, there's two states - "about to be <state>" and
> "really <state>". This seems like it might be a source of problems, and was
> definitely a source of confusion while reading. Anyway, probably not worth
> messing with here, but I thought I'd mention it.

That is not perse true atm, the Download state is correct, if you set it to be canceled is not about to be, is canceled, the main reason is that the DownloadQueue atm ensures that there is a singled download at a time (being a SingleDo...

Read more...

Revision history for this message
Manuel de la Peña (mandel) wrote :

> Also, my usual grumpy complaint that even though it's short, this still seems
> like at least two independent branches worth of changes. The error state fix
> is trivially reviewable, but the other part is delaying it.

Sorry I pushed in the wrong branch and though it would not be a huge problem.

133. By Manuel de la Peña

Merged smart-ignore-sslerrors into network-errors-management.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
134. By Manuel de la Peña

Merged smart-ignore-sslerrors into network-errors-management.

135. By Manuel de la Peña

Merged smart-ignore-sslerrors into network-errors-management.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Mike McCracken (mikemc) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'libubuntudownloadmanager/download_queue.cpp'
--- libubuntudownloadmanager/download_queue.cpp 2013-09-09 16:05:49 +0000
+++ libubuntudownloadmanager/download_queue.cpp 2013-09-23 11:39:12 +0000
@@ -145,7 +145,7 @@
145 Download::State state = currentDownload->state();145 Download::State state = currentDownload->state();
146 if (state == Download::CANCEL || state == Download::FINISH146 if (state == Download::CANCEL || state == Download::FINISH
147 || state == Download::ERROR) {147 || state == Download::ERROR) {
148 qDebug() << "States is CANCEL || FINISH";148 qDebug() << "State is CANCEL || FINISH || ERROR";
149 remove(_current);149 remove(_current);
150 _current = "";150 _current = "";
151 } else if (!currentDownload->canDownload()151 } else if (!currentDownload->canDownload()
152152
=== modified file 'libubuntudownloadmanager/group_download.cpp'
--- libubuntudownloadmanager/group_download.cpp 2013-09-18 11:25:47 +0000
+++ libubuntudownloadmanager/group_download.cpp 2013-09-23 11:39:12 +0000
@@ -18,7 +18,6 @@
1818
19#include <QDebug>19#include <QDebug>
20#include "./download_adaptor.h"20#include "./download_adaptor.h"
21#include "./download_queue.h"
22#include "./single_download.h"21#include "./single_download.h"
23#include "./uuid_factory.h"22#include "./uuid_factory.h"
24#include "./group_download.h"23#include "./group_download.h"
@@ -68,7 +67,6 @@
68 QCryptographicHash::Algorithm algo,67 QCryptographicHash::Algorithm algo,
69 bool isGSMDownloadAllowed) {68 bool isGSMDownloadAllowed) {
70 Q_Q(GroupDownload);69 Q_Q(GroupDownload);
71 _q = QSharedPointer<DownloadQueue>(new DownloadQueue(_networkInfo));
72 QVariantMap metadata = q->metadata();70 QVariantMap metadata = q->metadata();
73 QMap<QString, QString> headers = q->headers();71 QMap<QString, QString> headers = q->headers();
7472
@@ -110,23 +108,19 @@
110 q->connect(singleDownload, SIGNAL(finished(const QString&)),108 q->connect(singleDownload, SIGNAL(finished(const QString&)),
111 q, SLOT(onFinished(const QString&)));109 q, SLOT(onFinished(const QString&)));
112 qDebug() << "Signals connected.";110 qDebug() << "Signals connected.";
113 _q->add(singleDownload);
114 }111 }
115 }112 }
116113
117 void cancelDownload() {114 void cancelDownload() {
118 qDebug() << __PRETTY_FUNCTION__;115 qDebug() << __PRETTY_FUNCTION__;
119 Q_Q(GroupDownload);116 Q_Q(GroupDownload);
120 // loop over the events in reverse order and if the downloads and117 foreach(SingleDownload* download, _downloads) {
121 // if the are no cancelled do it
122 for (int index = _downloads.count() - 1; index >= 0; index--) {
123 qDebug() << "Index is" << index;
124 SingleDownload* download = _downloads[index];
125 Download::State state = download->state();118 Download::State state = download->state();
126 if (state != Download::FINISH && state != Download::ERROR119 if (state != Download::FINISH && state != Download::ERROR
127 && state != Download::CANCEL) {120 && state != Download::CANCEL) {
128 qDebug() << "Canceling download of " << download->url();121 qDebug() << "Canceling download of " << download->url();
129 download->cancel();122 download->cancel();
123 download->cancelDownload();
130 }124 }
131 }125 }
132126
@@ -142,14 +136,12 @@
142136
143 void pauseDownload() {137 void pauseDownload() {
144 Q_Q(GroupDownload);138 Q_Q(GroupDownload);
145 // loop over the events in reverse order and if the downloads and139 foreach(SingleDownload* download, _downloads) {
146 // if the are no paused or canceled do it
147 for (int index = _downloads.count() - 1; index >= 0; index--) {
148 SingleDownload* download = _downloads[index];
149 Download::State state = download->state();140 Download::State state = download->state();
150 if (state == Download::START || state == Download::RESUME) {141 if (state == Download::START || state == Download::RESUME) {
151 qDebug() << "Pausing download of " << download->url();142 qDebug() << "Pausing download of " << download->url();
152 download->pause();143 download->pause();
144 download->pauseDownload();
153 }145 }
154 }146 }
155 emit q->paused(true);147 emit q->paused(true);
@@ -161,6 +153,7 @@
161 Download::State state = download->state();153 Download::State state = download->state();
162 if (state == Download::PAUSE) {154 if (state == Download::PAUSE) {
163 download->resume();155 download->resume();
156 download->resumeDownload();
164 }157 }
165 }158 }
166 emit q->resumed(true);159 emit q->resumed(true);
@@ -172,6 +165,7 @@
172 Download::State state = download->state();165 Download::State state = download->state();
173 if (state == Download::IDLE) {166 if (state == Download::IDLE) {
174 download->start();167 download->start();
168 download->startDownload();
175 }169 }
176 }170 }
177 emit q->started(true);171 emit q->started(true);
@@ -223,7 +217,7 @@
223 _fileManager->remove(file);217 _fileManager->remove(file);
224 }218 }
225 QString errorMsg = sender->url().toString() + ":" + error;219 QString errorMsg = sender->url().toString() + ":" + error;
226 emit q->error(errorMsg);220 q->emitError(errorMsg);
227 }221 }
228222
229 void onProgress(qulonglong received, qulonglong total) {223 void onProgress(qulonglong received, qulonglong total) {
@@ -288,7 +282,6 @@
288 QStringList _finishedDownloads;282 QStringList _finishedDownloads;
289 QMap<QUrl, QPair<qulonglong, qulonglong> > _downloadsProgress;283 QMap<QUrl, QPair<qulonglong, qulonglong> > _downloadsProgress;
290 QSharedPointer<SystemNetworkInfo> _networkInfo;284 QSharedPointer<SystemNetworkInfo> _networkInfo;
291 QSharedPointer<DownloadQueue> _q;
292 QSharedPointer<DownloadFactory> _downFactory;285 QSharedPointer<DownloadFactory> _downFactory;
293 QSharedPointer<FileManager> _fileManager;286 QSharedPointer<FileManager> _fileManager;
294 GroupDownload* q_ptr;287 GroupDownload* q_ptr;
295288
=== modified file 'ubuntu-download-manager-tests/test_group_download.cpp'
--- ubuntu-download-manager-tests/test_group_download.cpp 2013-09-16 15:57:06 +0000
+++ ubuntu-download-manager-tests/test_group_download.cpp 2013-09-23 11:39:12 +0000
@@ -656,6 +656,7 @@
656 QList<MethodData> calledMethods = _fileManager->calledMethods();656 QList<MethodData> calledMethods = _fileManager->calledMethods();
657 QCOMPARE(0, calledMethods.count());657 QCOMPARE(0, calledMethods.count());
658 QCOMPARE(spy.count(), 1);658 QCOMPARE(spy.count(), 1);
659 QCOMPARE(Download::ERROR, group->state());
659}660}
660661
661void662void
@@ -688,6 +689,7 @@
688 QList<MethodData> calledMethods = _fileManager->calledMethods();689 QList<MethodData> calledMethods = _fileManager->calledMethods();
689 QCOMPARE(2, calledMethods.count());690 QCOMPARE(2, calledMethods.count());
690 QCOMPARE(spy.count(), 1);691 QCOMPARE(spy.count(), 1);
692 QCOMPARE(Download::ERROR, group->state());
691}693}
692694
693void695void

Subscribers

People subscribed via source and target branches