Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: ios/chrome/browser/reading_list/reading_list_download_service.cc

Issue 2351113003: Reading list downloader retries on recoverable error (Closed)
Patch Set: Fix looping issue Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ios/chrome/browser/reading_list/reading_list_download_service.h" 5 #include "ios/chrome/browser/reading_list/reading_list_download_service.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "ios/chrome/browser/reading_list/reading_list_entry.h" 12 #include "ios/chrome/browser/reading_list/reading_list_entry.h"
13 #include "ios/chrome/browser/reading_list/reading_list_model.h" 13 #include "ios/chrome/browser/reading_list/reading_list_model.h"
14 #include "ios/web/public/web_thread.h"
15
16 namespace {
17 // Number of time the download must fail before the download occurs only in
18 // wifi.
19 const int kNumberOfFailsBeforeWifiOnly = 5;
20 // Number of time the download must fail before we give up trying to download
21 // it.
22 const int kNumberOfFailsBeforeStop = 7;
23 } // namespace
14 24
15 ReadingListDownloadService::ReadingListDownloadService( 25 ReadingListDownloadService::ReadingListDownloadService(
16 ReadingListModel* reading_list_model, 26 ReadingListModel* reading_list_model,
17 dom_distiller::DomDistillerService* distiller_service, 27 dom_distiller::DomDistillerService* distiller_service,
18 PrefService* prefs, 28 PrefService* prefs,
19 base::FilePath chrome_profile_path) 29 base::FilePath chrome_profile_path)
20 : reading_list_model_(reading_list_model) { 30 : reading_list_model_(reading_list_model),
31 had_connection_(!net::NetworkChangeNotifier::IsOffline()),
32 weak_ptr_factory_(this) {
21 DCHECK(reading_list_model); 33 DCHECK(reading_list_model);
22 url_downloader_ = base::MakeUnique<URLDownloader>( 34 url_downloader_ = base::MakeUnique<URLDownloader>(
23 distiller_service, prefs, chrome_profile_path, 35 distiller_service, prefs, chrome_profile_path,
24 base::Bind(&ReadingListDownloadService::OnDownloadEnd, 36 base::Bind(&ReadingListDownloadService::OnDownloadEnd,
25 base::Unretained(this)), 37 base::Unretained(this)),
26 base::Bind(&ReadingListDownloadService::OnDeleteEnd, 38 base::Bind(&ReadingListDownloadService::OnDeleteEnd,
27 base::Unretained(this))); 39 base::Unretained(this)));
40 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
28 } 41 }
29 42
30 ReadingListDownloadService::~ReadingListDownloadService() {} 43 ReadingListDownloadService::~ReadingListDownloadService() {
44 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
45 }
31 46
32 void ReadingListDownloadService::Initialize() { 47 void ReadingListDownloadService::Initialize() {
33 reading_list_model_->AddObserver(this); 48 reading_list_model_->AddObserver(this);
34 } 49 }
35 50
36 void ReadingListDownloadService::Shutdown() { 51 void ReadingListDownloadService::Shutdown() {
37 reading_list_model_->RemoveObserver(this); 52 reading_list_model_->RemoveObserver(this);
38 } 53 }
39 54
40 void ReadingListDownloadService::ReadingListModelLoaded( 55 void ReadingListDownloadService::ReadingListModelLoaded(
(...skipping 13 matching lines...) Expand all
54 const ReadingListModel* model, 69 const ReadingListModel* model,
55 size_t index) { 70 size_t index) {
56 DCHECK_EQ(reading_list_model_, model); 71 DCHECK_EQ(reading_list_model_, model);
57 RemoveDownloadedEntry(model->GetUnreadEntryAtIndex(index)); 72 RemoveDownloadedEntry(model->GetUnreadEntryAtIndex(index));
58 } 73 }
59 74
60 void ReadingListDownloadService::ReadingListWillAddUnreadEntry( 75 void ReadingListDownloadService::ReadingListWillAddUnreadEntry(
61 const ReadingListModel* model, 76 const ReadingListModel* model,
62 const ReadingListEntry& entry) { 77 const ReadingListEntry& entry) {
63 DCHECK_EQ(reading_list_model_, model); 78 DCHECK_EQ(reading_list_model_, model);
64 DownloadEntry(entry); 79 ScheduleDownloadEntry(entry);
65 } 80 }
66 81
67 void ReadingListDownloadService::ReadingListWillAddReadEntry( 82 void ReadingListDownloadService::ReadingListWillAddReadEntry(
68 const ReadingListModel* model, 83 const ReadingListModel* model,
69 const ReadingListEntry& entry) { 84 const ReadingListEntry& entry) {
70 DCHECK_EQ(reading_list_model_, model); 85 DCHECK_EQ(reading_list_model_, model);
71 DownloadEntry(entry); 86 ScheduleDownloadEntry(entry);
72 } 87 }
73 88
74 void ReadingListDownloadService::DownloadAllEntries() { 89 void ReadingListDownloadService::DownloadAllEntries() {
75 DCHECK(reading_list_model_->loaded()); 90 DCHECK(reading_list_model_->loaded());
76 size_t size = reading_list_model_->unread_size(); 91 size_t size = reading_list_model_->unread_size();
77 for (size_t i = 0; i < size; i++) { 92 for (size_t i = 0; i < size; i++) {
78 const ReadingListEntry& entry = 93 const ReadingListEntry& entry =
79 reading_list_model_->GetUnreadEntryAtIndex(i); 94 reading_list_model_->GetUnreadEntryAtIndex(i);
80 this->DownloadEntry(entry); 95 this->ScheduleDownloadEntry(entry);
81 } 96 }
82 size = reading_list_model_->read_size(); 97 size = reading_list_model_->read_size();
83 for (size_t i = 0; i < size; i++) { 98 for (size_t i = 0; i < size; i++) {
84 const ReadingListEntry& entry = reading_list_model_->GetReadEntryAtIndex(i); 99 const ReadingListEntry& entry = reading_list_model_->GetReadEntryAtIndex(i);
85 this->DownloadEntry(entry); 100 this->ScheduleDownloadEntry(entry);
86 } 101 }
87 } 102 }
88 103
104 void ReadingListDownloadService::ScheduleDownloadEntry(
105 const ReadingListEntry& entry) {
106 DCHECK(reading_list_model_->loaded());
107 if (entry.DistilledState() == ReadingListEntry::ERROR ||
108 entry.DistilledState() == ReadingListEntry::PROCESSED)
109 return;
110
111 web::WebThread::PostDelayedTask(
112 web::WebThread::UI, FROM_HERE,
113 base::Bind(&ReadingListDownloadService::DownloadEntryFromURL,
114 weak_ptr_factory_.GetWeakPtr(), entry.URL()),
115 entry.TimeUntilNextTry());
116 }
117
118 void ReadingListDownloadService::ScheduleDownloadEntryFromURL(const GURL& url) {
119 auto download_callback =
120 base::Bind(&ReadingListDownloadService::ScheduleDownloadEntry,
121 base::Unretained(this));
122 reading_list_model_->CallbackEntryURL(url, download_callback);
123 }
124
125 void ReadingListDownloadService::DownloadEntryFromURL(const GURL& url) {
126 auto download_callback = base::Bind(
127 &ReadingListDownloadService::DownloadEntry, base::Unretained(this));
128 reading_list_model_->CallbackEntryURL(url, download_callback);
129 }
130
89 void ReadingListDownloadService::DownloadEntry(const ReadingListEntry& entry) { 131 void ReadingListDownloadService::DownloadEntry(const ReadingListEntry& entry) {
90 DCHECK(reading_list_model_->loaded()); 132 DCHECK(reading_list_model_->loaded());
91 if (entry.DistilledState() != ReadingListEntry::ERROR) { 133 if (entry.DistilledState() == ReadingListEntry::ERROR ||
134 entry.DistilledState() == ReadingListEntry::PROCESSED)
135 return;
136
137 if (net::NetworkChangeNotifier::IsOffline()) {
138 // There is no connection, save it for download only if we did not exceed
139 // the maximaxum number of tries.
140 if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeWifiOnly)
141 url_to_download_cellular_.push_back(entry.URL());
142 if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeStop)
143 url_to_download_wifi_.push_back(entry.URL());
144 return;
145 }
146
147 // There is a connection.
148 if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeWifiOnly) {
149 // Try to download the page, whatever the connection.
92 reading_list_model_->SetEntryDistilledState(entry.URL(), 150 reading_list_model_->SetEntryDistilledState(entry.URL(),
93 ReadingListEntry::PROCESSING); 151 ReadingListEntry::PROCESSING);
94 url_downloader_->DownloadOfflineURL(entry.URL()); 152 url_downloader_->DownloadOfflineURL(entry.URL());
153
154 } else if (entry.FailedDownloadCounter() < kNumberOfFailsBeforeStop) {
155 // Try to download the page only if the connection is wifi.
156 if (net::NetworkChangeNotifier::GetConnectionType() ==
157 net::NetworkChangeNotifier::CONNECTION_WIFI) {
158 // The connection is wifi, download the page.
159 reading_list_model_->SetEntryDistilledState(entry.URL(),
160 ReadingListEntry::PROCESSING);
161 url_downloader_->DownloadOfflineURL(entry.URL());
162
163 } else {
164 // The connection is not wifi, save it for download when the connection
165 // changes to wifi.
166 url_to_download_wifi_.push_back(entry.URL());
167 }
95 } 168 }
96 } 169 }
97 170
98 void ReadingListDownloadService::RemoveDownloadedEntry( 171 void ReadingListDownloadService::RemoveDownloadedEntry(
99 const ReadingListEntry& entry) { 172 const ReadingListEntry& entry) {
100 DCHECK(reading_list_model_->loaded()); 173 DCHECK(reading_list_model_->loaded());
101 url_downloader_->RemoveOfflineURL(entry.URL()); 174 url_downloader_->RemoveOfflineURL(entry.URL());
102 } 175 }
103 176
104 void ReadingListDownloadService::OnDownloadEnd( 177 void ReadingListDownloadService::OnDownloadEnd(
105 const GURL& url, 178 const GURL& url,
106 URLDownloader::SuccessState success, 179 URLDownloader::SuccessState success,
107 const GURL& distilled_url, 180 const GURL& distilled_url,
108 const std::string& title) { 181 const std::string& title) {
109 DCHECK(reading_list_model_->loaded()); 182 DCHECK(reading_list_model_->loaded());
110 if ((success == URLDownloader::DOWNLOAD_SUCCESS || 183 if ((success == URLDownloader::DOWNLOAD_SUCCESS ||
111 success == URLDownloader::DOWNLOAD_EXISTS) && 184 success == URLDownloader::DOWNLOAD_EXISTS) &&
112 distilled_url.is_valid()) { 185 distilled_url.is_valid()) {
113 reading_list_model_->SetEntryDistilledURL(url, distilled_url); 186 reading_list_model_->SetEntryDistilledURL(url, distilled_url);
187
114 } else if (success == URLDownloader::ERROR_RETRY) { 188 } else if (success == URLDownloader::ERROR_RETRY) {
115 reading_list_model_->SetEntryDistilledState(url, 189 reading_list_model_->SetEntryDistilledState(url,
116 ReadingListEntry::WILL_RETRY); 190 ReadingListEntry::WILL_RETRY);
191 ScheduleDownloadEntryFromURL(url);
192
117 } else if (success == URLDownloader::ERROR_PERMANENT) { 193 } else if (success == URLDownloader::ERROR_PERMANENT) {
118 reading_list_model_->SetEntryDistilledState(url, ReadingListEntry::ERROR); 194 reading_list_model_->SetEntryDistilledState(url, ReadingListEntry::ERROR);
119 } 195 }
120 } 196 }
121 197
122 void ReadingListDownloadService::OnDeleteEnd(const GURL& url, bool success) { 198 void ReadingListDownloadService::OnDeleteEnd(const GURL& url, bool success) {
123 // Nothing to update as this is only called when deleting reading list entries 199 // Nothing to update as this is only called when deleting reading list entries
124 } 200 }
201
202 void ReadingListDownloadService::OnConnectionTypeChanged(
203 net::NetworkChangeNotifier::ConnectionType type) {
204 if (type == net::NetworkChangeNotifier::CONNECTION_NONE) {
205 had_connection_ = false;
206 return;
207 }
208
209 if (!had_connection_) {
210 had_connection_ = true;
211 for (auto& url : url_to_download_cellular_) {
212 ScheduleDownloadEntryFromURL(url);
213 }
214 }
215 if (type == net::NetworkChangeNotifier::CONNECTION_WIFI) {
216 for (auto& url : url_to_download_wifi_) {
217 ScheduleDownloadEntryFromURL(url);
218 }
219 }
220 }
OLDNEW
« no previous file with comments | « ios/chrome/browser/reading_list/reading_list_download_service.h ('k') | ios/chrome/browser/reading_list/reading_list_entry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698