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
1=== modified file 'libubuntudownloadmanager/download_queue.cpp'
2--- libubuntudownloadmanager/download_queue.cpp 2013-09-09 16:05:49 +0000
3+++ libubuntudownloadmanager/download_queue.cpp 2013-09-23 11:39:12 +0000
4@@ -145,7 +145,7 @@
5 Download::State state = currentDownload->state();
6 if (state == Download::CANCEL || state == Download::FINISH
7 || state == Download::ERROR) {
8- qDebug() << "States is CANCEL || FINISH";
9+ qDebug() << "State is CANCEL || FINISH || ERROR";
10 remove(_current);
11 _current = "";
12 } else if (!currentDownload->canDownload()
13
14=== modified file 'libubuntudownloadmanager/group_download.cpp'
15--- libubuntudownloadmanager/group_download.cpp 2013-09-18 11:25:47 +0000
16+++ libubuntudownloadmanager/group_download.cpp 2013-09-23 11:39:12 +0000
17@@ -18,7 +18,6 @@
18
19 #include <QDebug>
20 #include "./download_adaptor.h"
21-#include "./download_queue.h"
22 #include "./single_download.h"
23 #include "./uuid_factory.h"
24 #include "./group_download.h"
25@@ -68,7 +67,6 @@
26 QCryptographicHash::Algorithm algo,
27 bool isGSMDownloadAllowed) {
28 Q_Q(GroupDownload);
29- _q = QSharedPointer<DownloadQueue>(new DownloadQueue(_networkInfo));
30 QVariantMap metadata = q->metadata();
31 QMap<QString, QString> headers = q->headers();
32
33@@ -110,23 +108,19 @@
34 q->connect(singleDownload, SIGNAL(finished(const QString&)),
35 q, SLOT(onFinished(const QString&)));
36 qDebug() << "Signals connected.";
37- _q->add(singleDownload);
38 }
39 }
40
41 void cancelDownload() {
42 qDebug() << __PRETTY_FUNCTION__;
43 Q_Q(GroupDownload);
44- // loop over the events in reverse order and if the downloads and
45- // if the are no cancelled do it
46- for (int index = _downloads.count() - 1; index >= 0; index--) {
47- qDebug() << "Index is" << index;
48- SingleDownload* download = _downloads[index];
49+ foreach(SingleDownload* download, _downloads) {
50 Download::State state = download->state();
51 if (state != Download::FINISH && state != Download::ERROR
52 && state != Download::CANCEL) {
53 qDebug() << "Canceling download of " << download->url();
54 download->cancel();
55+ download->cancelDownload();
56 }
57 }
58
59@@ -142,14 +136,12 @@
60
61 void pauseDownload() {
62 Q_Q(GroupDownload);
63- // loop over the events in reverse order and if the downloads and
64- // if the are no paused or canceled do it
65- for (int index = _downloads.count() - 1; index >= 0; index--) {
66- SingleDownload* download = _downloads[index];
67+ foreach(SingleDownload* download, _downloads) {
68 Download::State state = download->state();
69 if (state == Download::START || state == Download::RESUME) {
70 qDebug() << "Pausing download of " << download->url();
71 download->pause();
72+ download->pauseDownload();
73 }
74 }
75 emit q->paused(true);
76@@ -161,6 +153,7 @@
77 Download::State state = download->state();
78 if (state == Download::PAUSE) {
79 download->resume();
80+ download->resumeDownload();
81 }
82 }
83 emit q->resumed(true);
84@@ -172,6 +165,7 @@
85 Download::State state = download->state();
86 if (state == Download::IDLE) {
87 download->start();
88+ download->startDownload();
89 }
90 }
91 emit q->started(true);
92@@ -223,7 +217,7 @@
93 _fileManager->remove(file);
94 }
95 QString errorMsg = sender->url().toString() + ":" + error;
96- emit q->error(errorMsg);
97+ q->emitError(errorMsg);
98 }
99
100 void onProgress(qulonglong received, qulonglong total) {
101@@ -288,7 +282,6 @@
102 QStringList _finishedDownloads;
103 QMap<QUrl, QPair<qulonglong, qulonglong> > _downloadsProgress;
104 QSharedPointer<SystemNetworkInfo> _networkInfo;
105- QSharedPointer<DownloadQueue> _q;
106 QSharedPointer<DownloadFactory> _downFactory;
107 QSharedPointer<FileManager> _fileManager;
108 GroupDownload* q_ptr;
109
110=== modified file 'ubuntu-download-manager-tests/test_group_download.cpp'
111--- ubuntu-download-manager-tests/test_group_download.cpp 2013-09-16 15:57:06 +0000
112+++ ubuntu-download-manager-tests/test_group_download.cpp 2013-09-23 11:39:12 +0000
113@@ -656,6 +656,7 @@
114 QList<MethodData> calledMethods = _fileManager->calledMethods();
115 QCOMPARE(0, calledMethods.count());
116 QCOMPARE(spy.count(), 1);
117+ QCOMPARE(Download::ERROR, group->state());
118 }
119
120 void
121@@ -688,6 +689,7 @@
122 QList<MethodData> calledMethods = _fileManager->calledMethods();
123 QCOMPARE(2, calledMethods.count());
124 QCOMPARE(spy.count(), 1);
125+ QCOMPARE(Download::ERROR, group->state());
126 }
127
128 void

Subscribers

People subscribed via source and target branches