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

Side by Side Diff: components/precache/content/precache_manager.cc

Issue 1961153003: Add pause/resume functionality to precache (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added a proto Created 4 years, 7 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/precache/content/precache_manager.h" 5 #include "components/precache/content/precache_manager.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/files/file_path.h" 13 #include "base/files/file_path.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/field_trial.h" 15 #include "base/metrics/field_trial.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "components/history/core/browser/history_service.h" 18 #include "components/history/core/browser/history_service.h"
19 #include "components/precache/core/precache_database.h" 19 #include "components/precache/core/precache_database.h"
20 #include "components/precache/core/precache_switches.h" 20 #include "components/precache/core/precache_switches.h"
21 #include "components/precache/core/proto/unfinished_work.pb.h"
21 #include "components/prefs/pref_service.h" 22 #include "components/prefs/pref_service.h"
22 #include "components/sync_driver/sync_service.h" 23 #include "components/sync_driver/sync_service.h"
23 #include "components/variations/variations_associated_data.h" 24 #include "components/variations/variations_associated_data.h"
24 #include "content/public/browser/browser_context.h" 25 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/storage_partition.h" 27 #include "content/public/browser/storage_partition.h"
27 #include "net/base/network_change_notifier.h" 28 #include "net/base/network_change_notifier.h"
28 29
29 using content::BrowserThread; 30 using content::BrowserThread;
30 31
(...skipping 10 matching lines...) Expand all
41 42
42 namespace precache { 43 namespace precache {
43 44
44 size_t NumTopHosts() { 45 size_t NumTopHosts() {
45 return kNumTopHosts; 46 return kNumTopHosts;
46 } 47 }
47 48
48 PrecacheManager::PrecacheManager( 49 PrecacheManager::PrecacheManager(
49 content::BrowserContext* browser_context, 50 content::BrowserContext* browser_context,
50 const sync_driver::SyncService* const sync_service, 51 const sync_driver::SyncService* const sync_service,
51 const history::HistoryService* const history_service) 52 const history::HistoryService* const history_service,
53 std::unique_ptr<PrecacheDatabase> precache_database,
54 const base::FilePath& db_path)
52 : browser_context_(browser_context), 55 : browser_context_(browser_context),
53 sync_service_(sync_service), 56 sync_service_(sync_service),
54 history_service_(history_service), 57 history_service_(history_service),
55 precache_database_(new PrecacheDatabase()),
56 is_precaching_(false) { 58 is_precaching_(false) {
57 base::FilePath db_path(browser_context_->GetPath().Append( 59 precache_database_ = std::move(precache_database);
58 base::FilePath(FILE_PATH_LITERAL("PrecacheDatabase"))));
59 60
60 BrowserThread::PostTask( 61 BrowserThread::PostTask(
61 BrowserThread::DB, FROM_HERE, 62 BrowserThread::DB, FROM_HERE,
62 base::Bind(base::IgnoreResult(&PrecacheDatabase::Init), 63 base::Bind(base::IgnoreResult(&PrecacheDatabase::Init),
63 base::Unretained(precache_database_.get()), db_path)); 64 base::Unretained(precache_database_.get()), db_path));
64 } 65 }
65 66
66 PrecacheManager::~PrecacheManager() { 67 PrecacheManager::~PrecacheManager() {
67 // DeleteSoon posts a non-nestable task to the task runner, so any previously 68 // DeleteSoon posts a non-nestable task to the task runner, so any previously
68 // posted tasks that rely on an Unretained precache_database_ will finish 69 // posted tasks that rely on an Unretained precache_database_ will finish
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 const PrecacheCompletionCallback& precache_completion_callback) { 116 const PrecacheCompletionCallback& precache_completion_callback) {
116 DCHECK_CURRENTLY_ON(BrowserThread::UI); 117 DCHECK_CURRENTLY_ON(BrowserThread::UI);
117 118
118 if (is_precaching_) { 119 if (is_precaching_) {
119 DLOG(WARNING) << "Cannot start precaching because precaching is already " 120 DLOG(WARNING) << "Cannot start precaching because precaching is already "
120 "in progress."; 121 "in progress.";
121 return; 122 return;
122 } 123 }
123 precache_completion_callback_ = precache_completion_callback; 124 precache_completion_callback_ = precache_completion_callback;
124 125
126 is_precaching_ = true;
127 BrowserThread::PostTaskAndReplyWithResult(
128 BrowserThread::DB,
129 FROM_HERE,
130 base::Bind(&PrecacheDatabase::GetUnfinishedWork,
131 base::Unretained(precache_database_.get())),
132 base::Bind(&PrecacheManager::OnGetUnfinishedWorkDone, AsWeakPtr()));
133 }
134
135 void PrecacheManager::OnGetUnfinishedWorkDone(
136 std::unique_ptr<PrecacheUnfinishedWork> unfinished_work) {
137 if (base::Time::Now() - base::Time::FromInternalValue(
138 unfinished_work->start_time()) > base::TimeDelta::FromHours(6)) {
139 unfinished_work.reset(new PrecacheUnfinishedWork);
140 }
141 unfinished_work_ = std::move(unfinished_work);
142 bool needs_top_hosts = unfinished_work_->top_host_size() == 0;
143
125 if (IsInExperimentGroup()) { 144 if (IsInExperimentGroup()) {
126 is_precaching_ = true;
127
128 BrowserThread::PostTask( 145 BrowserThread::PostTask(
129 BrowserThread::DB, FROM_HERE, 146 BrowserThread::DB, FROM_HERE,
130 base::Bind(&PrecacheDatabase::DeleteExpiredPrecacheHistory, 147 base::Bind(&PrecacheDatabase::DeleteExpiredPrecacheHistory,
131 base::Unretained(precache_database_.get()), 148 base::Unretained(precache_database_.get()),
132 base::Time::Now())); 149 base::Time::Now()));
133 150
134 // Request NumTopHosts() top hosts. Note that PrecacheFetcher is further 151 // Request NumTopHosts() top hosts. Note that PrecacheFetcher is further
135 // bound by the value of PrecacheConfigurationSettings.top_sites_count, as 152 // bound by the value of PrecacheConfigurationSettings.top_sites_count, as
136 // retrieved from the server. 153 // retrieved from the server.
137 history_service_->TopHosts( 154 if (needs_top_hosts) {
138 NumTopHosts(), 155 history_service_->TopHosts(
139 base::Bind(&PrecacheManager::OnHostsReceived, AsWeakPtr())); 156 NumTopHosts(),
157 base::Bind(&PrecacheManager::OnHostsReceived, AsWeakPtr()));
158 } else {
159 std::vector<std::string> hosts;
160 for (int i = 0; i < unfinished_work_->top_host_size(); ++i) {
sclittle 2016/05/19 01:59:45 Could the hosts just be stored in the unfinished_w
bengr 2016/05/19 23:19:31 Done.
161 if (unfinished_work_->top_host(i).has_hostname())
162 hosts.push_back(unfinished_work_->top_host(i).hostname());
163 }
164 InitializeAndStartFetcher(hosts);
165 }
140 } else if (IsInControlGroup()) { 166 } else if (IsInControlGroup()) {
141 // Set is_precaching_ so that the longer delay is placed between calls to
142 // TopHosts.
143 is_precaching_ = true;
144
145 // Calculate TopHosts solely for metrics purposes. 167 // Calculate TopHosts solely for metrics purposes.
168 if (needs_top_hosts) {
146 history_service_->TopHosts( 169 history_service_->TopHosts(
147 NumTopHosts(), 170 NumTopHosts(),
148 base::Bind(&PrecacheManager::OnHostsReceivedThenDone, AsWeakPtr())); 171 base::Bind(&PrecacheManager::OnHostsReceivedThenDone, AsWeakPtr()));
172 } else {
173 OnDone();
174 }
149 } else { 175 } else {
150 if (PrecachingAllowed() != AllowedType::PENDING) { 176 if (PrecachingAllowed() != AllowedType::PENDING) {
151 // We are not waiting on the sync backend to be initialized. The user 177 // We are not waiting on the sync backend to be initialized. The user
152 // either is not in the field trial, or does not have sync enabled. 178 // either is not in the field trial, or does not have sync enabled.
153 // Pretend that precaching started, so that the PrecacheServiceLauncher 179 // Pretend that precaching started, so that the PrecacheServiceLauncher
154 // doesn't try to start it again. 180 // doesn't try to start it again.
155 is_precaching_ = true;
156 } 181 }
157 182
158 OnDone(); 183 OnDone();
159 } 184 }
160 } 185 }
161 186
162 void PrecacheManager::CancelPrecaching() { 187 void PrecacheManager::CancelPrecaching() {
163 DCHECK_CURRENTLY_ON(BrowserThread::UI); 188 DCHECK_CURRENTLY_ON(BrowserThread::UI);
164
165 if (!is_precaching_) { 189 if (!is_precaching_) {
166 // Do nothing if precaching is not in progress. 190 // Do nothing if precaching is not in progress.
167 return; 191 return;
168 } 192 }
169 is_precaching_ = false; 193 is_precaching_ = false;
194 // If cancellation occurs after StartPrecaching but before OnHostsReceived,
195 // is_precaching will be true, but the precache_fetcher_ will not yet be
196 // constructed.
197 if (precache_fetcher_) {
198 std::unique_ptr<PrecacheUnfinishedWork> unfinished_work =
199 precache_fetcher_->GetUnfinishedWork();
200 for (int i = 0; i < unfinished_work_->top_host_size(); ++i) {
201 if (unfinished_work_->top_host(i).has_hostname()) {
202 unfinished_work->mutable_top_host(i)->CopyFrom(
203 unfinished_work_->top_host(i));
204 }
205 }
206 BrowserThread::PostTaskAndReplyWithResult(
207 BrowserThread::DB,
208 FROM_HERE,
209 base::Bind(&PrecacheDatabase::SaveUnfinishedWork,
210 base::Unretained(precache_database_.get()),
211 base::Passed(&unfinished_work)),
212 base::Bind(&PrecacheManager::OnSaveUnfinishedWorkDone, AsWeakPtr()));
213 } else {
214 precache_completion_callback_.Reset();
215 }
216 }
170 217
218 void PrecacheManager::OnSaveUnfinishedWorkDone(bool /* success */) {
171 // Destroying the |precache_fetcher_| will cancel any fetch in progress. 219 // Destroying the |precache_fetcher_| will cancel any fetch in progress.
172 precache_fetcher_.reset(); 220 precache_fetcher_.reset();
173 221
174 // Uninitialize the callback so that any scoped_refptrs in it are released. 222 // Uninitialize the callback so that any scoped_refptrs in it are released.
175 precache_completion_callback_.Reset(); 223 precache_completion_callback_.Reset();
176 } 224 }
177 225
178 bool PrecacheManager::IsPrecaching() const { 226 bool PrecacheManager::IsPrecaching() const {
179 DCHECK_CURRENTLY_ON(BrowserThread::UI); 227 DCHECK_CURRENTLY_ON(BrowserThread::UI);
180 return is_precaching_; 228 return is_precaching_;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 base::Bind(&PrecacheDatabase::ClearHistory, 291 base::Bind(&PrecacheDatabase::ClearHistory,
244 base::Unretained(precache_database_.get()))); 292 base::Unretained(precache_database_.get())));
245 } 293 }
246 294
247 void PrecacheManager::Shutdown() { 295 void PrecacheManager::Shutdown() {
248 CancelPrecaching(); 296 CancelPrecaching();
249 } 297 }
250 298
251 void PrecacheManager::OnDone() { 299 void PrecacheManager::OnDone() {
252 DCHECK_CURRENTLY_ON(BrowserThread::UI); 300 DCHECK_CURRENTLY_ON(BrowserThread::UI);
253
254 precache_fetcher_.reset(); 301 precache_fetcher_.reset();
255 302
256 // Run completion callback if not null. It's null if the client is in the 303 // Run completion callback if not null. It's null if the client is in the
257 // Control group and CancelPrecaching is called before TopHosts computation 304 // Control group and CancelPrecaching is called before TopHosts computation
258 // finishes. 305 // finishes.
259 if (!precache_completion_callback_.is_null()) { 306 if (!precache_completion_callback_.is_null()) {
260 precache_completion_callback_.Run(!is_precaching_); 307 precache_completion_callback_.Run(!is_precaching_);
261 // Uninitialize the callback so that any scoped_refptrs in it are released. 308 // Uninitialize the callback so that any scoped_refptrs in it are released.
262 precache_completion_callback_.Reset(); 309 precache_completion_callback_.Reset();
263 } 310 }
264 311
265 is_precaching_ = false; 312 is_precaching_ = false;
266 } 313 }
267 314
268 void PrecacheManager::OnHostsReceived( 315 void PrecacheManager::OnHostsReceived(
269 const history::TopHostsList& host_counts) { 316 const history::TopHostsList& host_counts) {
270 DCHECK_CURRENTLY_ON(BrowserThread::UI); 317 DCHECK_CURRENTLY_ON(BrowserThread::UI);
271 318
319 std::vector<std::string> hosts;
320 for (const auto& host_count : host_counts)
321 hosts.push_back(host_count.first);
322 InitializeAndStartFetcher(hosts);
323 }
324
325 void PrecacheManager::InitializeAndStartFetcher(
326 const std::vector<std::string>& hosts) {
272 if (!is_precaching_) { 327 if (!is_precaching_) {
273 // Don't start precaching if it was canceled while waiting for the list of 328 // Don't start precaching if it was canceled while waiting for the list of
274 // hosts. 329 // hosts.
275 return; 330 return;
276 } 331 }
277
278 std::vector<std::string> hosts;
279 for (const auto& host_count : host_counts)
280 hosts.push_back(host_count.first);
281
282 // Start precaching. 332 // Start precaching.
283 precache_fetcher_.reset(new PrecacheFetcher( 333 precache_fetcher_.reset(new PrecacheFetcher(
284 hosts, 334 hosts,
285 content::BrowserContext::GetDefaultStoragePartition(browser_context_)-> 335 content::BrowserContext::GetDefaultStoragePartition(browser_context_)->
286 GetURLRequestContext(), 336 GetURLRequestContext(),
287 GURL(variations::GetVariationParamValue( 337 GURL(variations::GetVariationParamValue(
288 kPrecacheFieldTrialName, kConfigURLParam)), 338 kPrecacheFieldTrialName, kConfigURLParam)),
289 variations::GetVariationParamValue( 339 variations::GetVariationParamValue(
290 kPrecacheFieldTrialName, kManifestURLPrefixParam), 340 kPrecacheFieldTrialName, kManifestURLPrefixParam),
341 unfinished_work_.get(),
291 this)); 342 this));
292 precache_fetcher_->Start(); 343 precache_fetcher_->Start();
293 } 344 }
294 345
295 void PrecacheManager::OnHostsReceivedThenDone( 346 void PrecacheManager::OnHostsReceivedThenDone(
296 const history::TopHostsList& host_counts) { 347 const history::TopHostsList& host_counts) {
297 OnDone(); 348 OnDone();
298 } 349 }
299 350
300 } // namespace precache 351 } // namespace precache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698