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

Side by Side Diff: components/precache/core/precache_fetcher.cc

Issue 2335913002: Add daily quota for precache (Closed)
Patch Set: rebased 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 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/core/precache_fetcher.h" 5 #include "components/precache/core/precache_fetcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/base64.h" 12 #include "base/base64.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/callback.h" 15 #include "base/callback.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/compiler_specific.h" 17 #include "base/compiler_specific.h"
18 #include "base/containers/hash_tables.h" 18 #include "base/containers/hash_tables.h"
19 #include "base/location.h" 19 #include "base/location.h"
20 #include "base/logging.h" 20 #include "base/logging.h"
21 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
22 #include "base/memory/ref_counted.h" 22 #include "base/memory/ref_counted.h"
23 #include "base/metrics/histogram_macros.h" 23 #include "base/metrics/histogram_macros.h"
24 #include "base/sha1.h" 24 #include "base/sha1.h"
25 #include "base/strings/string_piece.h" 25 #include "base/strings/string_piece.h"
26 #include "base/task_runner_util.h" 26 #include "base/task_runner_util.h"
27 #include "components/precache/core/precache_database.h" 27 #include "components/precache/core/precache_database.h"
28 #include "components/precache/core/precache_switches.h" 28 #include "components/precache/core/precache_switches.h"
29 #include "components/precache/core/proto/precache.pb.h" 29 #include "components/precache/core/proto/precache.pb.h"
30 #include "components/precache/core/proto/quota.pb.h"
30 #include "components/precache/core/proto/unfinished_work.pb.h" 31 #include "components/precache/core/proto/unfinished_work.pb.h"
31 #include "net/base/completion_callback.h" 32 #include "net/base/completion_callback.h"
32 #include "net/base/escape.h" 33 #include "net/base/escape.h"
33 #include "net/base/io_buffer.h" 34 #include "net/base/io_buffer.h"
34 #include "net/base/load_flags.h" 35 #include "net/base/load_flags.h"
35 #include "net/base/net_errors.h" 36 #include "net/base/net_errors.h"
36 #include "net/base/url_util.h" 37 #include "net/base/url_util.h"
37 #include "net/http/http_response_headers.h" 38 #include "net/http/http_response_headers.h"
38 #include "net/url_request/url_fetcher_response_writer.h" 39 #include "net/url_request/url_fetcher_response_writer.h"
39 #include "net/url_request/url_request_context_getter.h" 40 #include "net/url_request/url_request_context_getter.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 GetResourceURLBase64Hash(unused_urls))); 198 GetResourceURLBase64Hash(unused_urls)));
198 } else { 199 } else {
199 hosts_info.push_back( 200 hosts_info.push_back(
200 ManifestHostInfo(PrecacheReferrerHostEntry::kInvalidId, host, 201 ManifestHostInfo(PrecacheReferrerHostEntry::kInvalidId, host,
201 std::string(), std::string())); 202 std::string(), std::string()));
202 } 203 }
203 } 204 }
204 return hosts_info; 205 return hosts_info;
205 } 206 }
206 207
208 PrecacheQuota RetrieveQuotaInfo(
209 const base::WeakPtr<PrecacheDatabase>& precache_database) {
210 PrecacheQuota quota;
211 if (precache_database) {
212 quota = precache_database->GetQuota();
213 }
214 return quota;
215 }
216
217 // Returns true if the |quota| time has expired.
218 bool IsQuotaTimeExpired(const PrecacheQuota& quota,
219 const base::Time& time_now) {
220 // Quota expires one day after the start time.
221 base::Time start_time = base::Time::FromInternalValue(quota.start_time());
222 return start_time > time_now ||
223 start_time + base::TimeDelta::FromDays(1) < time_now;
224 }
225
207 } // namespace 226 } // namespace
208 227
209 PrecacheFetcher::Fetcher::Fetcher( 228 PrecacheFetcher::Fetcher::Fetcher(
210 net::URLRequestContextGetter* request_context, 229 net::URLRequestContextGetter* request_context,
211 const GURL& url, 230 const GURL& url,
212 const std::string& referrer, 231 const std::string& referrer,
213 const base::Callback<void(const Fetcher&)>& callback, 232 const base::Callback<void(const Fetcher&)>& callback,
214 bool is_resource_request, 233 bool is_resource_request,
215 size_t max_bytes) 234 size_t max_bytes)
216 : request_context_(request_context), 235 : request_context_(request_context),
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 pool_.Add(base::MakeUnique<Fetcher>( 482 pool_.Add(base::MakeUnique<Fetcher>(
464 request_context_.get(), config_url, std::string(), 483 request_context_.get(), config_url, std::string(),
465 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, AsWeakPtr()), 484 base::Bind(&PrecacheFetcher::OnConfigFetchComplete, AsWeakPtr()),
466 false /* is_resource_request */, std::numeric_limits<int32_t>::max())); 485 false /* is_resource_request */, std::numeric_limits<int32_t>::max()));
467 } 486 }
468 487
469 void PrecacheFetcher::StartNextResourceFetch() { 488 void PrecacheFetcher::StartNextResourceFetch() {
470 DCHECK(unfinished_work_->has_config_settings()); 489 DCHECK(unfinished_work_->has_config_settings());
471 while (!resources_to_fetch_.empty() && pool_.IsAvailable()) { 490 while (!resources_to_fetch_.empty() && pool_.IsAvailable()) {
472 const auto& resource = resources_to_fetch_.front(); 491 const auto& resource = resources_to_fetch_.front();
473 const size_t max_bytes = 492 const size_t max_bytes = std::min(
493 quota_.remaining(),
474 std::min(unfinished_work_->config_settings().max_bytes_per_resource(), 494 std::min(unfinished_work_->config_settings().max_bytes_per_resource(),
475 unfinished_work_->config_settings().max_bytes_total() - 495 unfinished_work_->config_settings().max_bytes_total() -
476 unfinished_work_->total_bytes()); 496 unfinished_work_->total_bytes()));
477 VLOG(3) << "Fetching " << resource.first << " " << resource.second; 497 VLOG(3) << "Fetching " << resource.first << " " << resource.second;
478 pool_.Add(base::MakeUnique<Fetcher>( 498 pool_.Add(base::MakeUnique<Fetcher>(
479 request_context_.get(), resource.first, resource.second, 499 request_context_.get(), resource.first, resource.second,
480 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, AsWeakPtr()), 500 base::Bind(&PrecacheFetcher::OnResourceFetchComplete, AsWeakPtr()),
481 true /* is_resource_request */, max_bytes)); 501 true /* is_resource_request */, max_bytes));
482 502
483 resources_to_fetch_.pop_front(); 503 resources_to_fetch_.pop_front();
484 } 504 }
485 } 505 }
486 506
(...skipping 16 matching lines...) Expand all
503 size_t remaining_manifest_urls_to_fetch, 523 size_t remaining_manifest_urls_to_fetch,
504 size_t remaining_resource_urls_to_fetch) { 524 size_t remaining_resource_urls_to_fetch) {
505 RecordCompletionStatistics(*unfinished_work_, 525 RecordCompletionStatistics(*unfinished_work_,
506 remaining_manifest_urls_to_fetch, 526 remaining_manifest_urls_to_fetch,
507 remaining_resource_urls_to_fetch); 527 remaining_resource_urls_to_fetch);
508 precache_delegate_->OnDone(); 528 precache_delegate_->OnDone();
509 } 529 }
510 530
511 void PrecacheFetcher::StartNextFetch() { 531 void PrecacheFetcher::StartNextFetch() {
512 DCHECK(unfinished_work_->has_config_settings()); 532 DCHECK(unfinished_work_->has_config_settings());
513 // If over the precache total size cap, then stop prefetching. 533
514 if (unfinished_work_->total_bytes() > 534 // If over the precache total size cap or daily quota, then stop prefetching.
515 unfinished_work_->config_settings().max_bytes_total()) { 535 if ((unfinished_work_->total_bytes() >
536 unfinished_work_->config_settings().max_bytes_total()) ||
537 quota_.remaining() == 0) {
516 size_t pending_manifests_in_pool = 0; 538 size_t pending_manifests_in_pool = 0;
517 size_t pending_resources_in_pool = 0; 539 size_t pending_resources_in_pool = 0;
518 for (const auto& element_pair : pool_.elements()) { 540 for (const auto& element_pair : pool_.elements()) {
519 const Fetcher* fetcher = element_pair.first; 541 const Fetcher* fetcher = element_pair.first;
520 if (fetcher->is_resource_request()) 542 if (fetcher->is_resource_request())
521 pending_resources_in_pool++; 543 pending_resources_in_pool++;
522 else if (fetcher->url() != config_url_) 544 else if (fetcher->url() != config_url_)
523 pending_manifests_in_pool++; 545 pending_manifests_in_pool++;
524 } 546 }
525 pool_.DeleteAll(); 547 pool_.DeleteAll();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 manifest.manifest_url, "manifest", 641 manifest.manifest_url, "manifest",
620 std::to_string(manifest.manifest_id)); 642 std::to_string(manifest.manifest_id));
621 manifest.manifest_url = net::AppendOrReplaceQueryParameter( 643 manifest.manifest_url = net::AppendOrReplaceQueryParameter(
622 manifest.manifest_url, "used_resources", manifest.used_url_hash); 644 manifest.manifest_url, "used_resources", manifest.used_url_hash);
623 manifest.manifest_url = net::AppendOrReplaceQueryParameter( 645 manifest.manifest_url = net::AppendOrReplaceQueryParameter(
624 manifest.manifest_url, "unused_resources", manifest.unused_url_hash); 646 manifest.manifest_url, "unused_resources", manifest.unused_url_hash);
625 DCHECK(manifest.manifest_url.is_valid()); 647 DCHECK(manifest.manifest_url.is_valid());
626 } 648 }
627 } 649 }
628 unfinished_work_->set_num_manifest_urls(top_hosts_to_fetch_.size()); 650 unfinished_work_->set_num_manifest_urls(top_hosts_to_fetch_.size());
651
652 PostTaskAndReplyWithResult(
653 db_task_runner_.get(), FROM_HERE,
654 base::Bind(&RetrieveQuotaInfo, precache_database_),
655 base::Bind(&PrecacheFetcher::OnQuotaInfoRetrieved, AsWeakPtr()));
656 }
657
658 void PrecacheFetcher::OnQuotaInfoRetrieved(const PrecacheQuota& quota) {
659 quota_ = quota;
660 base::Time time_now = base::Time::Now();
661 if (IsQuotaTimeExpired(quota_, time_now)) {
662 // This is a new day. Update daily quota, that starts today and expires by
663 // end of today.
664 quota_.set_start_time(time_now.LocalMidnight().ToInternalValue());
665 quota_.set_remaining(
666 unfinished_work_->config_settings().daily_quota_total());
667 db_task_runner_->PostTask(
668 FROM_HERE,
669 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_));
670 }
629 StartNextFetch(); 671 StartNextFetch();
630 } 672 }
631 673
632 ManifestHostInfo::ManifestHostInfo(int64_t manifest_id, 674 ManifestHostInfo::ManifestHostInfo(int64_t manifest_id,
633 const std::string& hostname, 675 const std::string& hostname,
634 const std::string& used_url_hash, 676 const std::string& used_url_hash,
635 const std::string& unused_url_hash) 677 const std::string& unused_url_hash)
636 : manifest_id(manifest_id), 678 : manifest_id(manifest_id),
637 hostname(hostname), 679 hostname(hostname),
638 used_url_hash(used_url_hash), 680 used_url_hash(used_url_hash),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 731
690 pool_.Delete(source); 732 pool_.Delete(source);
691 733
692 // The resource has already been put in the cache during the fetch process, so 734 // The resource has already been put in the cache during the fetch process, so
693 // nothing more needs to be done for the resource. 735 // nothing more needs to be done for the resource.
694 StartNextFetch(); 736 StartNextFetch();
695 } 737 }
696 738
697 void PrecacheFetcher::UpdateStats(int64_t response_bytes, 739 void PrecacheFetcher::UpdateStats(int64_t response_bytes,
698 int64_t network_response_bytes) { 740 int64_t network_response_bytes) {
741 DCHECK_LE(0, response_bytes);
742 DCHECK_LE(0, network_response_bytes);
743
699 unfinished_work_->set_total_bytes( 744 unfinished_work_->set_total_bytes(
700 unfinished_work_->total_bytes() + response_bytes); 745 unfinished_work_->total_bytes() + response_bytes);
701 unfinished_work_->set_network_bytes( 746 unfinished_work_->set_network_bytes(
702 unfinished_work_->network_bytes() + network_response_bytes); 747 unfinished_work_->network_bytes() + network_response_bytes);
748
749 if (!IsQuotaTimeExpired(quota_, base::Time::Now())) {
750 uint64_t used_bytes = static_cast<uint64_t>(network_response_bytes);
751 int64_t remaining =
752 static_cast<int64_t>(quota_.remaining()) - network_response_bytes;
753 if (remaining < 0)
754 remaining = 0;
755 quota_.set_remaining(
756 used_bytes > quota_.remaining() ? 0U : quota_.remaining() - used_bytes);
757 db_task_runner_->PostTask(
758 FROM_HERE,
759 base::Bind(&PrecacheDatabase::SaveQuota, precache_database_, quota_));
760 }
703 } 761 }
704 762
705 } // namespace precache 763 } // namespace precache
OLDNEW
« no previous file with comments | « components/precache/core/precache_fetcher.h ('k') | components/precache/core/precache_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698