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

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: test fix Created 4 years, 6 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
60 BrowserThread::PostTask( 59 BrowserThread::PostTask(
61 BrowserThread::DB, FROM_HERE, 60 BrowserThread::DB, FROM_HERE,
62 base::Bind(base::IgnoreResult(&PrecacheDatabase::Init), 61 base::Bind(base::IgnoreResult(&PrecacheDatabase::Init),
63 base::Unretained(precache_database_.get()), db_path)); 62 base::Unretained(precache_database_.get()), db_path));
64 } 63 }
65 64
66 PrecacheManager::~PrecacheManager() { 65 PrecacheManager::~PrecacheManager() {
67 // DeleteSoon posts a non-nestable task to the task runner, so any previously 66 // 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 67 // posted tasks that rely on an Unretained precache_database_ will finish
69 // before it is deleted. 68 // before it is deleted.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 const PrecacheCompletionCallback& precache_completion_callback) { 114 const PrecacheCompletionCallback& precache_completion_callback) {
116 DCHECK_CURRENTLY_ON(BrowserThread::UI); 115 DCHECK_CURRENTLY_ON(BrowserThread::UI);
117 116
118 if (is_precaching_) { 117 if (is_precaching_) {
119 DLOG(WARNING) << "Cannot start precaching because precaching is already " 118 DLOG(WARNING) << "Cannot start precaching because precaching is already "
120 "in progress."; 119 "in progress.";
121 return; 120 return;
122 } 121 }
123 precache_completion_callback_ = precache_completion_callback; 122 precache_completion_callback_ = precache_completion_callback;
124 123
124 is_precaching_ = true;
125 BrowserThread::PostTaskAndReplyWithResult(
126 BrowserThread::DB,
127 FROM_HERE,
128 base::Bind(&PrecacheDatabase::GetUnfinishedWork,
129 base::Unretained(precache_database_.get())),
130 base::Bind(&PrecacheManager::OnGetUnfinishedWorkDone, AsWeakPtr()));
131 }
132
133 void PrecacheManager::OnGetUnfinishedWorkDone(
134 std::unique_ptr<PrecacheUnfinishedWork> unfinished_work) {
135 if (!unfinished_work->has_start_time() ||
136 base::Time::Now() - base::Time::FromInternalValue(
137 unfinished_work->start_time()) > base::TimeDelta::FromHours(6)) {
138 PrecacheFetcher::RecordCompletionStatistics(
139 *unfinished_work,
140 unfinished_work->manifest_size(),
141 unfinished_work->resource_size());
142 unfinished_work.reset(new PrecacheUnfinishedWork());
143 unfinished_work->set_start_time(base::Time::Now().ToInternalValue());
144 }
145 unfinished_work_ = std::move(unfinished_work);
146 bool needs_top_hosts = unfinished_work_->top_host_size() == 0;
147
125 if (IsInExperimentGroup()) { 148 if (IsInExperimentGroup()) {
126 is_precaching_ = true;
127
128 BrowserThread::PostTask( 149 BrowserThread::PostTask(
129 BrowserThread::DB, FROM_HERE, 150 BrowserThread::DB, FROM_HERE,
130 base::Bind(&PrecacheDatabase::DeleteExpiredPrecacheHistory, 151 base::Bind(&PrecacheDatabase::DeleteExpiredPrecacheHistory,
131 base::Unretained(precache_database_.get()), 152 base::Unretained(precache_database_.get()),
132 base::Time::Now())); 153 base::Time::Now()));
133 154
134 // Request NumTopHosts() top hosts. Note that PrecacheFetcher is further 155 // Request NumTopHosts() top hosts. Note that PrecacheFetcher is further
135 // bound by the value of PrecacheConfigurationSettings.top_sites_count, as 156 // bound by the value of PrecacheConfigurationSettings.top_sites_count, as
136 // retrieved from the server. 157 // retrieved from the server.
137 history_service_->TopHosts( 158 if (needs_top_hosts) {
138 NumTopHosts(), 159 history_service_->TopHosts(
139 base::Bind(&PrecacheManager::OnHostsReceived, AsWeakPtr())); 160 NumTopHosts(),
161 base::Bind(&PrecacheManager::OnHostsReceived, AsWeakPtr()));
162 } else {
163 InitializeAndStartFetcher();
164 }
140 } else if (IsInControlGroup()) { 165 } 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. 166 // Calculate TopHosts solely for metrics purposes.
146 history_service_->TopHosts( 167 if (needs_top_hosts) {
147 NumTopHosts(), 168 history_service_->TopHosts(
148 base::Bind(&PrecacheManager::OnHostsReceivedThenDone, AsWeakPtr())); 169 NumTopHosts(),
170 base::Bind(&PrecacheManager::OnHostsReceivedThenDone, AsWeakPtr()));
171 } else {
172 OnDone();
173 }
149 } else { 174 } else {
150 if (PrecachingAllowed() != AllowedType::PENDING) { 175 if (PrecachingAllowed() != AllowedType::PENDING) {
151 // We are not waiting on the sync backend to be initialized. The user 176 // 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. 177 // either is not in the field trial, or does not have sync enabled.
153 // Pretend that precaching started, so that the PrecacheServiceLauncher 178 // Pretend that precaching started, so that the PrecacheServiceLauncher
154 // doesn't try to start it again. 179 // doesn't try to start it again.
155 is_precaching_ = true;
156 } 180 }
157 181
158 OnDone(); 182 OnDone();
159 } 183 }
160 } 184 }
161 185
162 void PrecacheManager::CancelPrecaching() { 186 void PrecacheManager::CancelPrecaching() {
163 DCHECK_CURRENTLY_ON(BrowserThread::UI); 187 DCHECK_CURRENTLY_ON(BrowserThread::UI);
164
165 if (!is_precaching_) { 188 if (!is_precaching_) {
166 // Do nothing if precaching is not in progress. 189 // Do nothing if precaching is not in progress.
167 return; 190 return;
168 } 191 }
169 is_precaching_ = false; 192 is_precaching_ = false;
170 193 // If cancellation occurs after StartPrecaching but before OnHostsReceived,
171 // Destroying the |precache_fetcher_| will cancel any fetch in progress. 194 // is_precaching will be true, but the precache_fetcher_ will not yet be
172 precache_fetcher_.reset(); 195 // constructed.
173 196 if (precache_fetcher_) {
174 // Uninitialize the callback so that any scoped_refptrs in it are released. 197 std::unique_ptr<PrecacheUnfinishedWork> unfinished_work =
198 precache_fetcher_->CancelPrecaching();
199 BrowserThread::PostTask(
200 BrowserThread::DB,
201 FROM_HERE,
202 base::Bind(&PrecacheDatabase::SaveUnfinishedWork,
203 precache_database_->GetWeakPtr(),
204 base::Passed(&unfinished_work)));
205 // Destroying the |precache_fetcher_| will cancel any fetch in progress.
206 precache_fetcher_.reset();
207 }
175 precache_completion_callback_.Reset(); 208 precache_completion_callback_.Reset();
176 } 209 }
177 210
178 bool PrecacheManager::IsPrecaching() const { 211 bool PrecacheManager::IsPrecaching() const {
179 DCHECK_CURRENTLY_ON(BrowserThread::UI); 212 DCHECK_CURRENTLY_ON(BrowserThread::UI);
180 return is_precaching_; 213 return is_precaching_;
181 } 214 }
182 215
183 void PrecacheManager::RecordStatsForFetch(const GURL& url, 216 void PrecacheManager::RecordStatsForFetch(const GURL& url,
184 const GURL& referrer, 217 const GURL& referrer,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 base::Bind(&PrecacheDatabase::ClearHistory, 276 base::Bind(&PrecacheDatabase::ClearHistory,
244 base::Unretained(precache_database_.get()))); 277 base::Unretained(precache_database_.get())));
245 } 278 }
246 279
247 void PrecacheManager::Shutdown() { 280 void PrecacheManager::Shutdown() {
248 CancelPrecaching(); 281 CancelPrecaching();
249 } 282 }
250 283
251 void PrecacheManager::OnDone() { 284 void PrecacheManager::OnDone() {
252 DCHECK_CURRENTLY_ON(BrowserThread::UI); 285 DCHECK_CURRENTLY_ON(BrowserThread::UI);
253
254 precache_fetcher_.reset(); 286 precache_fetcher_.reset();
255 287
256 // Run completion callback if not null. It's null if the client is in the 288 // 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 289 // Control group and CancelPrecaching is called before TopHosts computation
258 // finishes. 290 // finishes.
259 if (!precache_completion_callback_.is_null()) { 291 if (!precache_completion_callback_.is_null()) {
260 precache_completion_callback_.Run(!is_precaching_); 292 precache_completion_callback_.Run(!is_precaching_);
261 // Uninitialize the callback so that any scoped_refptrs in it are released. 293 // Uninitialize the callback so that any scoped_refptrs in it are released.
262 precache_completion_callback_.Reset(); 294 precache_completion_callback_.Reset();
263 } 295 }
264 296
265 is_precaching_ = false; 297 is_precaching_ = false;
266 } 298 }
267 299
268 void PrecacheManager::OnHostsReceived( 300 void PrecacheManager::OnHostsReceived(
269 const history::TopHostsList& host_counts) { 301 const history::TopHostsList& host_counts) {
270 DCHECK_CURRENTLY_ON(BrowserThread::UI); 302 DCHECK_CURRENTLY_ON(BrowserThread::UI);
271 303
304 std::vector<std::string> hosts;
305 for (const auto& host_count : host_counts)
306 unfinished_work_->add_top_host()->set_hostname(host_count.first);
307 InitializeAndStartFetcher();
308 }
309
310 void PrecacheManager::InitializeAndStartFetcher() {
272 if (!is_precaching_) { 311 if (!is_precaching_) {
273 // Don't start precaching if it was canceled while waiting for the list of 312 // Don't start precaching if it was canceled while waiting for the list of
274 // hosts. 313 // hosts.
275 return; 314 return;
276 } 315 }
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. 316 // Start precaching.
283 precache_fetcher_.reset(new PrecacheFetcher( 317 precache_fetcher_.reset(new PrecacheFetcher(
284 hosts,
285 content::BrowserContext::GetDefaultStoragePartition(browser_context_)-> 318 content::BrowserContext::GetDefaultStoragePartition(browser_context_)->
286 GetURLRequestContext(), 319 GetURLRequestContext(),
287 GURL(variations::GetVariationParamValue( 320 GURL(variations::GetVariationParamValue(
288 kPrecacheFieldTrialName, kConfigURLParam)), 321 kPrecacheFieldTrialName, kConfigURLParam)),
289 variations::GetVariationParamValue( 322 variations::GetVariationParamValue(
290 kPrecacheFieldTrialName, kManifestURLPrefixParam), 323 kPrecacheFieldTrialName, kManifestURLPrefixParam),
324 std::move(unfinished_work_),
291 this)); 325 this));
292 precache_fetcher_->Start(); 326 precache_fetcher_->Start();
293 } 327 }
294 328
295 void PrecacheManager::OnHostsReceivedThenDone( 329 void PrecacheManager::OnHostsReceivedThenDone(
296 const history::TopHostsList& host_counts) { 330 const history::TopHostsList& host_counts) {
297 OnDone(); 331 OnDone();
298 } 332 }
299 333
300 } // namespace precache 334 } // namespace precache
OLDNEW
« no previous file with comments | « components/precache/content/precache_manager.h ('k') | components/precache/content/precache_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698