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

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

Powered by Google App Engine
This is Rietveld 408576698