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

Side by Side Diff: storage/browser/quota/quota_manager.cc

Issue 1403673002: Add Quota.TimeSinceOriginEvicted UMA histogram. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 5 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 "storage/browser/quota/quota_manager.h" 5 #include "storage/browser/quota/quota_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 // Preserve kMinimumPreserveForSystem disk space for system book-keeping 66 // Preserve kMinimumPreserveForSystem disk space for system book-keeping
67 // when returning the quota to unlimited apps/extensions. 67 // when returning the quota to unlimited apps/extensions.
68 // TODO(kinuko): This should be like 10% of the actual disk space. 68 // TODO(kinuko): This should be like 10% of the actual disk space.
69 // For now we simply use a constant as getting the disk size needs 69 // For now we simply use a constant as getting the disk size needs
70 // platform-dependent code. (http://crbug.com/178976) 70 // platform-dependent code. (http://crbug.com/178976)
71 int64 QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes; 71 int64 QuotaManager::kMinimumPreserveForSystem = 1024 * kMBytes;
72 72
73 const int QuotaManager::kEvictionIntervalInMilliSeconds = 73 const int QuotaManager::kEvictionIntervalInMilliSeconds =
74 30 * kMinutesInMilliSeconds; 74 30 * kMinutesInMilliSeconds;
75 75
76 const char QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram[] =
77 "Quota.TimeBetweenRepeatedOriginEvictions";
78
76 // Heuristics: assuming average cloud server allows a few Gigs storage 79 // Heuristics: assuming average cloud server allows a few Gigs storage
77 // on the server side and the storage needs to be shared for user data 80 // on the server side and the storage needs to be shared for user data
78 // and by multiple apps. 81 // and by multiple apps.
79 int64 QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes; 82 int64 QuotaManager::kSyncableStorageDefaultHostQuota = 500 * kMBytes;
80 83
81 namespace { 84 namespace {
82 85
83 void CountOriginType(const std::set<GURL>& origins, 86 void CountOriginType(const std::set<GURL>& origins,
84 SpecialStoragePolicy* policy, 87 SpecialStoragePolicy* policy,
85 size_t* protected_origins, 88 size_t* protected_origins,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 SpecialStoragePolicy* policy, 148 SpecialStoragePolicy* policy,
146 GURL* url, 149 GURL* url,
147 QuotaDatabase* database) { 150 QuotaDatabase* database) {
148 DCHECK(database); 151 DCHECK(database);
149 database->GetLRUOrigin(type, *exceptions, policy, url); 152 database->GetLRUOrigin(type, *exceptions, policy, url);
150 return true; 153 return true;
151 } 154 }
152 155
153 bool DeleteOriginInfoOnDBThread(const GURL& origin, 156 bool DeleteOriginInfoOnDBThread(const GURL& origin,
154 StorageType type, 157 StorageType type,
158 bool is_eviction,
155 QuotaDatabase* database) { 159 QuotaDatabase* database) {
156 DCHECK(database); 160 DCHECK(database);
157 return database->DeleteOriginInfo(origin, type); 161 if (!database->DeleteOriginInfo(origin, type))
162 return false;
163
164 // If the deletion is not due to an eviction, delete the entry in the eviction
165 // table as well due to privacy concerns.
166 if (!is_eviction)
167 return database->DeleteOriginLastEvictionTime(origin, type);
168
169 base::Time last_eviction_time;
170 if (!database->GetOriginLastEvictionTime(origin, type, &last_eviction_time))
171 return false;
172
173 base::Time now = base::Time::Now();
174 if (last_eviction_time != base::Time()) {
175 UMA_HISTOGRAM_LONG_TIMES(
176 QuotaManager::kTimeBetweenRepeatedOriginEvictionsHistogram,
177 now - last_eviction_time);
178 }
179
180 if (!database->SetOriginLastEvictionTime(origin, type, now))
181 return false;
182
183 return true;
michaeln 2015/10/16 20:50:50 could simplify this to return database->SetBlahBla
calamity 2015/10/20 00:18:30 Done.
158 } 184 }
159 185
160 bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins, 186 bool InitializeTemporaryOriginsInfoOnDBThread(const std::set<GURL>* origins,
161 QuotaDatabase* database) { 187 QuotaDatabase* database) {
162 DCHECK(database); 188 DCHECK(database);
163 if (database->IsOriginDatabaseBootstrapped()) 189 if (database->IsOriginDatabaseBootstrapped())
164 return true; 190 return true;
165 191
166 // Register existing origins with 0 last time access. 192 // Register existing origins with 0 last time access.
167 if (database->RegisterInitialOriginInfo(*origins, kStorageTypeTemporary)) { 193 if (database->RegisterInitialOriginInfo(*origins, kStorageTypeTemporary)) {
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 553
528 DISALLOW_COPY_AND_ASSIGN(GetUsageInfoTask); 554 DISALLOW_COPY_AND_ASSIGN(GetUsageInfoTask);
529 }; 555 };
530 556
531 class QuotaManager::OriginDataDeleter : public QuotaTask { 557 class QuotaManager::OriginDataDeleter : public QuotaTask {
532 public: 558 public:
533 OriginDataDeleter(QuotaManager* manager, 559 OriginDataDeleter(QuotaManager* manager,
534 const GURL& origin, 560 const GURL& origin,
535 StorageType type, 561 StorageType type,
536 int quota_client_mask, 562 int quota_client_mask,
563 bool is_eviction,
537 const StatusCallback& callback) 564 const StatusCallback& callback)
538 : QuotaTask(manager), 565 : QuotaTask(manager),
539 origin_(origin), 566 origin_(origin),
540 type_(type), 567 type_(type),
541 quota_client_mask_(quota_client_mask), 568 quota_client_mask_(quota_client_mask),
542 error_count_(0), 569 error_count_(0),
543 remaining_clients_(-1), 570 remaining_clients_(-1),
544 skipped_clients_(0), 571 skipped_clients_(0),
572 is_eviction_(is_eviction),
545 callback_(callback), 573 callback_(callback),
546 weak_factory_(this) {} 574 weak_factory_(this) {}
547 575
548 protected: 576 protected:
549 void Run() override { 577 void Run() override {
550 error_count_ = 0; 578 error_count_ = 0;
551 remaining_clients_ = manager()->clients_.size(); 579 remaining_clients_ = manager()->clients_.size();
552 for (QuotaClientList::iterator iter = manager()->clients_.begin(); 580 for (QuotaClientList::iterator iter = manager()->clients_.begin();
553 iter != manager()->clients_.end(); ++iter) { 581 iter != manager()->clients_.end(); ++iter) {
554 if (quota_client_mask_ & (*iter)->id()) { 582 if (quota_client_mask_ & (*iter)->id()) {
555 (*iter)->DeleteOriginData( 583 (*iter)->DeleteOriginData(
556 origin_, type_, 584 origin_, type_,
557 base::Bind(&OriginDataDeleter::DidDeleteOriginData, 585 base::Bind(&OriginDataDeleter::DidDeleteOriginData,
558 weak_factory_.GetWeakPtr())); 586 weak_factory_.GetWeakPtr()));
559 } else { 587 } else {
560 ++skipped_clients_; 588 ++skipped_clients_;
561 if (--remaining_clients_ == 0) 589 if (--remaining_clients_ == 0)
562 CallCompleted(); 590 CallCompleted();
563 } 591 }
564 } 592 }
565 } 593 }
566 594
567 void Completed() override { 595 void Completed() override {
568 if (error_count_ == 0) { 596 if (error_count_ == 0) {
569 // Only remove the entire origin if we didn't skip any client types. 597 // Only remove the entire origin if we didn't skip any client types.
570 if (skipped_clients_ == 0) 598 if (skipped_clients_ == 0)
571 manager()->DeleteOriginFromDatabase(origin_, type_); 599 manager()->DeleteOriginFromDatabase(origin_, type_, is_eviction_);
572 callback_.Run(kQuotaStatusOk); 600 callback_.Run(kQuotaStatusOk);
573 } else { 601 } else {
574 callback_.Run(kQuotaErrorInvalidModification); 602 callback_.Run(kQuotaErrorInvalidModification);
575 } 603 }
576 DeleteSoon(); 604 DeleteSoon();
577 } 605 }
578 606
579 void Aborted() override { 607 void Aborted() override {
580 callback_.Run(kQuotaErrorAbort); 608 callback_.Run(kQuotaErrorAbort);
581 DeleteSoon(); 609 DeleteSoon();
(...skipping 13 matching lines...) Expand all
595 QuotaManager* manager() const { 623 QuotaManager* manager() const {
596 return static_cast<QuotaManager*>(observer()); 624 return static_cast<QuotaManager*>(observer());
597 } 625 }
598 626
599 GURL origin_; 627 GURL origin_;
600 StorageType type_; 628 StorageType type_;
601 int quota_client_mask_; 629 int quota_client_mask_;
602 int error_count_; 630 int error_count_;
603 int remaining_clients_; 631 int remaining_clients_;
604 int skipped_clients_; 632 int skipped_clients_;
633 bool is_eviction_;
605 StatusCallback callback_; 634 StatusCallback callback_;
606 635
607 base::WeakPtrFactory<OriginDataDeleter> weak_factory_; 636 base::WeakPtrFactory<OriginDataDeleter> weak_factory_;
608 DISALLOW_COPY_AND_ASSIGN(OriginDataDeleter); 637 DISALLOW_COPY_AND_ASSIGN(OriginDataDeleter);
609 }; 638 };
610 639
611 class QuotaManager::HostDataDeleter : public QuotaTask { 640 class QuotaManager::HostDataDeleter : public QuotaTask {
612 public: 641 public:
613 HostDataDeleter(QuotaManager* manager, 642 HostDataDeleter(QuotaManager* manager,
614 const std::string& host, 643 const std::string& host,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 else 693 else
665 CallCompleted(); 694 CallCompleted();
666 } 695 }
667 } 696 }
668 697
669 void ScheduleOriginsDeletion() { 698 void ScheduleOriginsDeletion() {
670 remaining_deleters_ = origins_.size(); 699 remaining_deleters_ = origins_.size();
671 for (std::set<GURL>::const_iterator p = origins_.begin(); 700 for (std::set<GURL>::const_iterator p = origins_.begin();
672 p != origins_.end(); 701 p != origins_.end();
673 ++p) { 702 ++p) {
674 OriginDataDeleter* deleter = 703 OriginDataDeleter* deleter = new OriginDataDeleter(
675 new OriginDataDeleter( 704 manager(), *p, type_, quota_client_mask_, false,
676 manager(), *p, type_, quota_client_mask_, 705 base::Bind(&HostDataDeleter::DidDeleteOriginData,
677 base::Bind(&HostDataDeleter::DidDeleteOriginData, 706 weak_factory_.GetWeakPtr()));
678 weak_factory_.GetWeakPtr()));
679 deleter->Start(); 707 deleter->Start();
680 } 708 }
681 } 709 }
682 710
683 void DidDeleteOriginData(QuotaStatusCode status) { 711 void DidDeleteOriginData(QuotaStatusCode status) {
684 DCHECK_GT(remaining_deleters_, 0); 712 DCHECK_GT(remaining_deleters_, 0);
685 713
686 if (status != kQuotaStatusOk) 714 if (status != kQuotaStatusOk)
687 ++error_count_; 715 ++error_count_;
688 716
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 946
919 void QuotaManager::SetUsageCacheEnabled(QuotaClient::ID client_id, 947 void QuotaManager::SetUsageCacheEnabled(QuotaClient::ID client_id,
920 const GURL& origin, 948 const GURL& origin,
921 StorageType type, 949 StorageType type,
922 bool enabled) { 950 bool enabled) {
923 LazyInitialize(); 951 LazyInitialize();
924 DCHECK(GetUsageTracker(type)); 952 DCHECK(GetUsageTracker(type));
925 GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled); 953 GetUsageTracker(type)->SetUsageCacheEnabled(client_id, origin, enabled);
926 } 954 }
927 955
928 void QuotaManager::DeleteOriginData( 956 void QuotaManager::DeleteOriginData(const GURL& origin,
929 const GURL& origin, StorageType type, int quota_client_mask, 957 StorageType type,
930 const StatusCallback& callback) { 958 int quota_client_mask,
931 LazyInitialize(); 959 const StatusCallback& callback) {
932 960 DeleteOriginDataInternal(origin, type, quota_client_mask, false, callback);
933 if (origin.is_empty() || clients_.empty()) {
934 callback.Run(kQuotaStatusOk);
935 return;
936 }
937
938 DCHECK(origin == origin.GetOrigin());
939 OriginDataDeleter* deleter =
940 new OriginDataDeleter(this, origin, type, quota_client_mask, callback);
941 deleter->Start();
942 } 961 }
943 962
944 void QuotaManager::DeleteHostData(const std::string& host, 963 void QuotaManager::DeleteHostData(const std::string& host,
945 StorageType type, 964 StorageType type,
946 int quota_client_mask, 965 int quota_client_mask,
947 const StatusCallback& callback) { 966 const StatusCallback& callback) {
948 LazyInitialize(); 967 LazyInitialize();
949 968
950 if (host.empty() || clients_.empty()) { 969 if (host.empty() || clients_.empty()) {
951 callback.Run(kQuotaStatusOk); 970 callback.Run(kQuotaStatusOk);
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 void QuotaManager::StartEviction() { 1366 void QuotaManager::StartEviction() {
1348 DCHECK(!temporary_storage_evictor_.get()); 1367 DCHECK(!temporary_storage_evictor_.get());
1349 temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor( 1368 temporary_storage_evictor_.reset(new QuotaTemporaryStorageEvictor(
1350 this, kEvictionIntervalInMilliSeconds)); 1369 this, kEvictionIntervalInMilliSeconds));
1351 if (desired_available_space_ >= 0) 1370 if (desired_available_space_ >= 0)
1352 temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction( 1371 temporary_storage_evictor_->set_min_available_disk_space_to_start_eviction(
1353 desired_available_space_); 1372 desired_available_space_);
1354 temporary_storage_evictor_->Start(); 1373 temporary_storage_evictor_->Start();
1355 } 1374 }
1356 1375
1357 void QuotaManager::DeleteOriginFromDatabase( 1376 void QuotaManager::DeleteOriginFromDatabase(const GURL& origin,
1358 const GURL& origin, StorageType type) { 1377 StorageType type,
1378 bool is_eviction) {
1359 LazyInitialize(); 1379 LazyInitialize();
1360 if (db_disabled_) 1380 if (db_disabled_)
1361 return; 1381 return;
1362 1382
1363 PostTaskAndReplyWithResultForDBThread( 1383 PostTaskAndReplyWithResultForDBThread(
1364 FROM_HERE, 1384 FROM_HERE,
1365 base::Bind(&DeleteOriginInfoOnDBThread, origin, type), 1385 base::Bind(&DeleteOriginInfoOnDBThread, origin, type, is_eviction),
1366 base::Bind(&QuotaManager::DidDatabaseWork, 1386 base::Bind(&QuotaManager::DidDatabaseWork, weak_factory_.GetWeakPtr()));
1367 weak_factory_.GetWeakPtr()));
1368 } 1387 }
1369 1388
1370 void QuotaManager::DidOriginDataEvicted(QuotaStatusCode status) { 1389 void QuotaManager::DidOriginDataEvicted(QuotaStatusCode status) {
1371 DCHECK(io_thread_->BelongsToCurrentThread()); 1390 DCHECK(io_thread_->BelongsToCurrentThread());
1372 1391
1373 // We only try evict origins that are not in use, so basically 1392 // We only try evict origins that are not in use, so basically
1374 // deletion attempt for eviction should not fail. Let's record 1393 // deletion attempt for eviction should not fail. Let's record
1375 // the origin if we get error and exclude it from future eviction 1394 // the origin if we get error and exclude it from future eviction
1376 // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted). 1395 // if the error happens consistently (> kThresholdOfErrorsToBeBlacklisted).
1377 if (status != kQuotaStatusOk) 1396 if (status != kQuotaStatusOk)
1378 origins_in_error_[eviction_context_.evicted_origin]++; 1397 origins_in_error_[eviction_context_.evicted_origin]++;
1379 1398
1380 eviction_context_.evict_origin_data_callback.Run(status); 1399 eviction_context_.evict_origin_data_callback.Run(status);
1381 eviction_context_.evict_origin_data_callback.Reset(); 1400 eviction_context_.evict_origin_data_callback.Reset();
1382 } 1401 }
1383 1402
1403 void QuotaManager::DeleteOriginDataInternal(const GURL& origin,
1404 StorageType type,
1405 int quota_client_mask,
1406 bool is_eviction,
1407 const StatusCallback& callback) {
1408 LazyInitialize();
1409
1410 if (origin.is_empty() || clients_.empty()) {
1411 callback.Run(kQuotaStatusOk);
1412 return;
1413 }
1414
1415 DCHECK(origin == origin.GetOrigin());
1416 OriginDataDeleter* deleter = new OriginDataDeleter(
1417 this, origin, type, quota_client_mask, is_eviction, callback);
1418 deleter->Start();
1419 }
1420
1384 void QuotaManager::ReportHistogram() { 1421 void QuotaManager::ReportHistogram() {
1385 GetGlobalUsage(kStorageTypeTemporary, 1422 GetGlobalUsage(kStorageTypeTemporary,
1386 base::Bind( 1423 base::Bind(
1387 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram, 1424 &QuotaManager::DidGetTemporaryGlobalUsageForHistogram,
1388 weak_factory_.GetWeakPtr())); 1425 weak_factory_.GetWeakPtr()));
1389 GetGlobalUsage(kStorageTypePersistent, 1426 GetGlobalUsage(kStorageTypePersistent,
1390 base::Bind( 1427 base::Bind(
1391 &QuotaManager::DidGetPersistentGlobalUsageForHistogram, 1428 &QuotaManager::DidGetPersistentGlobalUsageForHistogram,
1392 weak_factory_.GetWeakPtr())); 1429 weak_factory_.GetWeakPtr()));
1393 } 1430 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 void QuotaManager::EvictOriginData(const GURL& origin, 1485 void QuotaManager::EvictOriginData(const GURL& origin,
1449 StorageType type, 1486 StorageType type,
1450 const EvictOriginDataCallback& callback) { 1487 const EvictOriginDataCallback& callback) {
1451 DCHECK(io_thread_->BelongsToCurrentThread()); 1488 DCHECK(io_thread_->BelongsToCurrentThread());
1452 DCHECK_EQ(type, kStorageTypeTemporary); 1489 DCHECK_EQ(type, kStorageTypeTemporary);
1453 1490
1454 eviction_context_.evicted_origin = origin; 1491 eviction_context_.evicted_origin = origin;
1455 eviction_context_.evicted_type = type; 1492 eviction_context_.evicted_type = type;
1456 eviction_context_.evict_origin_data_callback = callback; 1493 eviction_context_.evict_origin_data_callback = callback;
1457 1494
1458 DeleteOriginData(origin, type, QuotaClient::kAllClientsMask, 1495 DeleteOriginDataInternal(origin, type, QuotaClient::kAllClientsMask, true,
1459 base::Bind(&QuotaManager::DidOriginDataEvicted, 1496 base::Bind(&QuotaManager::DidOriginDataEvicted,
1460 weak_factory_.GetWeakPtr())); 1497 weak_factory_.GetWeakPtr()));
1461 } 1498 }
1462 1499
1463 void QuotaManager::GetUsageAndQuotaForEviction( 1500 void QuotaManager::GetUsageAndQuotaForEviction(
1464 const UsageAndQuotaCallback& callback) { 1501 const UsageAndQuotaCallback& callback) {
1465 DCHECK(io_thread_->BelongsToCurrentThread()); 1502 DCHECK(io_thread_->BelongsToCurrentThread());
1466 LazyInitialize(); 1503 LazyInitialize();
1467 1504
1468 UsageAndQuotaCallbackDispatcher* dispatcher = 1505 UsageAndQuotaCallbackDispatcher* dispatcher =
1469 new UsageAndQuotaCallbackDispatcher(this); 1506 new UsageAndQuotaCallbackDispatcher(this);
1470 GetUsageTracker(kStorageTypeTemporary) 1507 GetUsageTracker(kStorageTypeTemporary)
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 // |database_|, therefore we can be sure that database_ is alive when this 1662 // |database_|, therefore we can be sure that database_ is alive when this
1626 // task runs. 1663 // task runs.
1627 base::PostTaskAndReplyWithResult( 1664 base::PostTaskAndReplyWithResult(
1628 db_thread_.get(), 1665 db_thread_.get(),
1629 from_here, 1666 from_here,
1630 base::Bind(task, base::Unretained(database_.get())), 1667 base::Bind(task, base::Unretained(database_.get())),
1631 reply); 1668 reply);
1632 } 1669 }
1633 1670
1634 } // namespace storage 1671 } // namespace storage
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698