Merge lp:~dobey/unity-scope-click/without-crashing into lp:unity-scope-click

Proposed by dobey
Status: Rejected
Rejected by: Marcus Tomlinson
Proposed branch: lp:~dobey/unity-scope-click/without-crashing
Merge into: lp:unity-scope-click
Prerequisite: lp:~dobey/unity-scope-click/really-we-want-to-sign-all-the-requests
Diff against target: 231 lines (+56/-29)
6 files modified
libclickscope/click/download-manager.cpp (+29/-16)
libclickscope/click/download-manager.h (+3/-3)
libclickscope/click/preview.cpp (+4/-3)
libclickscope/click/preview.h (+1/-0)
libclickscope/click/qtbridge.h (+16/-0)
libclickscope/click/ubuntuone_credentials.cpp (+3/-7)
To merge this branch: bzr merge lp:~dobey/unity-scope-click/without-crashing
Reviewer Review Type Date Requested Status
Marcus Tomlinson (community) Disapprove
Review via email: mp+290774@code.launchpad.net

Commit message

Refactor the code to process Qt events while waiting on future into a template.
Wait for Qt callbacks from downloadmanager before continuing.

To post a comment you must log in.
443. By dobey

Use const references in the error callback args.

444. By dobey

Keep the cancellable around.

445. By dobey

Block in the preview on getting the progress object path.

446. By dobey

Call web::Client::call with full argument list.

447. By dobey

Revert the last change.

448. By dobey

Fix lambda arg declarations.

449. By dobey

Revert the addition of promise/future in preview.

450. By dobey

Oops, missed changing one callback to setting the promise.

451. By dobey

Use toStdString to convert from QString.

452. By dobey

Need to convert for qdebug now.

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :
review: Disapprove

Unmerged revisions

452. By dobey

Need to convert for qdebug now.

451. By dobey

Use toStdString to convert from QString.

450. By dobey

Oops, missed changing one callback to setting the promise.

449. By dobey

Revert the addition of promise/future in preview.

448. By dobey

Fix lambda arg declarations.

447. By dobey

Revert the last change.

446. By dobey

Call web::Client::call with full argument list.

445. By dobey

Block in the preview on getting the progress object path.

444. By dobey

Keep the cancellable around.

443. By dobey

Use const references in the error callback args.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libclickscope/click/download-manager.cpp'
2--- libclickscope/click/download-manager.cpp 2016-04-14 18:09:31 +0000
3+++ libclickscope/click/download-manager.cpp 2016-04-14 18:09:31 +0000
4@@ -28,6 +28,7 @@
5 */
6
7 #include "download-manager.h"
8+#include "qtbridge.h"
9
10 #include <QDebug>
11 #include <QObject>
12@@ -75,11 +76,14 @@
13 }
14
15 void DownloadManager::get_progress(const std::string& package_name,
16- const std::function<void (std::string)>& callback)
17+ const std::function<void (const std::string&)>& callback)
18 {
19+ std::promise<std::string> promise;
20+ auto future = promise.get_future();
21+
22 dm->getAllDownloadsWithMetadata(DOWNLOAD_APP_ID_KEY,
23 QString::fromStdString(package_name),
24- [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* downloads_list){
25+ [callback, package_name, &promise](const QString& /*key*/, const QString& /*value*/, DownloadsList* downloads_list){
26 // got downloads matching metadata
27 std::string object_path;
28 auto downloads = downloads_list->downloads();
29@@ -92,18 +96,21 @@
30 if (downloads.size() > 1) {
31 qWarning() << "More than one download with the same object path";
32 }
33- callback(object_path);
34- }, [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){
35+ promise.set_value(object_path);
36+ }, [callback, package_name, &promise](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){
37 // no downloads found
38 qDebug() << "No object path found for package" << QString::fromStdString(package_name);
39- callback("");
40+ promise.set_value("");
41 });
42+ qt::core::world::wait_for_future_ready<std::string>(future);
43+ auto result = future.get();
44+ callback(result);
45 }
46
47 click::web::Cancellable DownloadManager::start(const std::string& url,
48 const std::string& download_sha512,
49 const std::string& package_name,
50- const std::function<void (std::string, Error)>& callback)
51+ const std::function<void (const std::string&, const Error&)>& callback)
52 {
53 QSharedPointer<click::web::Response> response = client->call
54 (url, "HEAD", true);
55@@ -131,21 +138,26 @@
56 metadata,
57 headers);
58
59+ std::promise<std::pair<std::string, Error>> promise;
60+ auto future = promise.get_future();
61 dm->createDownload(downloadStruct,
62- [callback](Download* download) {
63+ [callback, &promise](Download* download) {
64 if (download->isError()) {
65- auto error = download->error()->errorString().toUtf8().data();
66- qDebug() << "Received error from ubuntu-download-manager:" << error;
67- callback(error, Error::DownloadInstallError);
68+ auto error = download->error()->errorString().toStdString();
69+ qDebug() << "Received error from ubuntu-download-manager:" << error.c_str();
70+ promise.set_value(std::pair<std::string, Error>{error, Error::DownloadInstallError});
71 } else {
72 download->start();
73- callback(download->id().toUtf8().data(), Error::NoError);
74+ promise.set_value(std::pair<std::string, Error>{download->id().toStdString(), Error::NoError});
75 }
76 },
77- [callback](Download* download) {
78- callback(download->error()->errorString().toUtf8().data(),
79- Error::DownloadInstallError);
80+ [callback, &promise](Download* download) {
81+ promise.set_value(std::pair<std::string, Error>{download->error()->errorString().toStdString(),
82+ Error::DownloadInstallError});
83 });
84+ qt::core::world::wait_for_future_ready<std::pair<std::string, Error>>(future);
85+ auto result = future.get();
86+ callback(result.first, result.second);
87 } else {
88 std::string error{"Unhandled HTTP response code: "};
89 error += status;
90@@ -159,10 +171,11 @@
91 case 401:
92 case 403:
93 client->invalidateCredentials();
94- callback(error.toUtf8().data(), Error::CredentialsError);
95+ callback(error.toStdString(), Error::CredentialsError);
96 break;
97 default:
98- callback(error.toUtf8().data(), Error::DownloadInstallError);
99+ callback(error.toStdString(), Error::DownloadInstallError);
100+ break;
101 }
102 });
103
104
105=== modified file 'libclickscope/click/download-manager.h'
106--- libclickscope/click/download-manager.h 2016-02-26 18:51:22 +0000
107+++ libclickscope/click/download-manager.h 2016-04-14 18:09:31 +0000
108@@ -67,12 +67,12 @@
109 virtual ~DownloadManager();
110
111 virtual void get_progress(const std::string& package_name,
112- const std::function<void (std::string)>& callback);
113+ const std::function<void (const std::string&)>& callback);
114 virtual click::web::Cancellable start(const std::string& url,
115 const std::string& download_sha512,
116 const std::string& package_name,
117- const std::function<void (std::string,
118- Error)>& callback);
119+ const std::function<void (const std::string&,
120+ const Error&)>& callback);
121
122 virtual void setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService);
123
124
125=== modified file 'libclickscope/click/preview.cpp'
126--- libclickscope/click/preview.cpp 2016-04-14 18:09:31 +0000
127+++ libclickscope/click/preview.cpp 2016-04-14 18:09:31 +0000
128@@ -346,6 +346,7 @@
129 reviews_operation.cancel();
130 submit_operation.cancel();
131 purchase_operation.cancel();
132+ download_operation.cancel();
133 }
134
135 scopes::PreviewWidget PreviewStrategy::build_other_metadata(const PackageDetails &details)
136@@ -734,8 +735,8 @@
137 std::promise<bool> promise;
138 auto future = promise.get_future();
139 run_under_qt([this, reply, &promise]() {
140- dm->start(download_url, download_sha512, result["name"].get_string(),
141- [this, reply, &promise] (std::string msg, DownloadManager::Error dmerr){
142+ download_operation = dm->start(download_url, download_sha512, result["name"].get_string(),
143+ [this, reply, &promise] (const std::string& msg, const DownloadManager::Error& dmerr){
144 switch (dmerr)
145 {
146 case DownloadManager::Error::DownloadInstallError:
147@@ -1233,7 +1234,7 @@
148 click::Reviews::Error reviewserror) {
149 std::string app_name = result["name"].get_string();
150 dm->get_progress(app_name,
151- [this, reply, reviewlist, reviewserror](std::string object_path){
152+ [this, reply, reviewlist, reviewserror](const std::string& object_path){
153 found_object_path = object_path;
154 scopes::PreviewWidgetList button_widgets;
155 if(found_object_path.empty()) {
156
157=== modified file 'libclickscope/click/preview.h'
158--- libclickscope/click/preview.h 2016-03-07 14:10:27 +0000
159+++ libclickscope/click/preview.h 2016-04-14 18:09:31 +0000
160@@ -209,6 +209,7 @@
161 scopes::OnlineAccountClient oa_client;
162 QSharedPointer<pay::Package> pay_package;
163 click::web::Cancellable purchase_operation;
164+ click::web::Cancellable download_operation;
165 };
166
167 class DownloadErrorPreview : public PreviewStrategy
168
169=== modified file 'libclickscope/click/qtbridge.h'
170--- libclickscope/click/qtbridge.h 2014-05-26 14:02:45 +0000
171+++ libclickscope/click/qtbridge.h 2016-04-14 18:09:31 +0000
172@@ -20,6 +20,7 @@
173 #ifndef QT_CORE_WORLD_BRIDGE_H_
174 #define QT_CORE_WORLD_BRIDGE_H_
175
176+#include<QCoreApplication>
177 #include <QObject>
178
179 #include <functional>
180@@ -80,6 +81,21 @@
181
182 return future;
183 }
184+
185+/**
186+ * @brief Waits for a promise to be fulfilled, without blocking Qt event loop;
187+ * @param future The future to wait on for ready state.
188+ */
189+template<typename T>
190+inline void wait_for_future_ready(const std::future<T>& future)
191+{
192+ std::future_status status = future.wait_for(std::chrono::milliseconds(0));
193+ while (status != std::future_status::ready) {
194+ QCoreApplication::processEvents();
195+ status = future.wait_for(std::chrono::milliseconds(100));
196+ }
197+}
198+
199 }
200 }
201 }
202
203=== modified file 'libclickscope/click/ubuntuone_credentials.cpp'
204--- libclickscope/click/ubuntuone_credentials.cpp 2016-04-14 18:09:31 +0000
205+++ libclickscope/click/ubuntuone_credentials.cpp 2016-04-14 18:09:31 +0000
206@@ -28,9 +28,10 @@
207 */
208
209 #include "ubuntuone_credentials.h"
210+#include "qtbridge.h"
211
212 #include <future>
213-#include <QCoreApplication>
214+
215
216 namespace u1 = UbuntuOne;
217
218@@ -72,12 +73,7 @@
219
220 getCredentials();
221
222- std::future_status status = future.wait_for(std::chrono::milliseconds(0));
223- while (status != std::future_status::ready) {
224- QCoreApplication::processEvents();
225- qDebug() << "Processed some events, waiting to process again.";
226- status = future.wait_for(std::chrono::milliseconds(100));
227- }
228+ qt::core::world::wait_for_future_ready<UbuntuOne::Token>(future);
229
230 _token = future.get();
231 QObject::disconnect(success);

Subscribers

People subscribed via source and target branches

to all changes: