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

Side by Side Diff: components/offline_pages/offline_page_model_impl.cc

Issue 2497703002: [Offline pages] Resetting offline page metadata store to handle LOAD/INIT failures (Closed)
Patch Set: Addressing comments form self-review Created 4 years, 1 month 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/offline_pages/offline_page_model_impl.h" 5 #include "components/offline_pages/offline_page_model_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 if (online_url_without_fragment == 640 if (online_url_without_fragment ==
641 id_page_pair.second.url.ReplaceComponents(remove_params)) { 641 id_page_pair.second.url.ReplaceComponents(remove_params)) {
642 result.push_back(id_page_pair.second); 642 result.push_back(id_page_pair.second);
643 } 643 }
644 } 644 }
645 645
646 callback.Run(result); 646 callback.Run(result);
647 } 647 }
648 648
649 void OfflinePageModelImpl::CheckMetadataConsistency() { 649 void OfflinePageModelImpl::CheckMetadataConsistency() {
650 DCHECK(is_loaded_);
651 archive_manager_->GetAllArchives( 650 archive_manager_->GetAllArchives(
652 base::Bind(&OfflinePageModelImpl::CheckMetadataConsistencyForArchivePaths, 651 base::Bind(&OfflinePageModelImpl::CheckMetadataConsistencyForArchivePaths,
653 weak_ptr_factory_.GetWeakPtr())); 652 weak_ptr_factory_.GetWeakPtr()));
654 } 653 }
655 654
656 void OfflinePageModelImpl::ExpirePages( 655 void OfflinePageModelImpl::ExpirePages(
657 const std::vector<int64_t>& offline_ids, 656 const std::vector<int64_t>& offline_ids,
658 const base::Time& expiration_time, 657 const base::Time& expiration_time,
659 const base::Callback<void(bool)>& callback) { 658 const base::Callback<void(bool)>& callback) {
660 std::vector<base::FilePath> paths_to_delete; 659 std::vector<base::FilePath> paths_to_delete;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 } else if (status == ItemActionStatus::ALREADY_EXISTS) { 784 } else if (status == ItemActionStatus::ALREADY_EXISTS) {
786 result = SavePageResult::ALREADY_EXISTS; 785 result = SavePageResult::ALREADY_EXISTS;
787 } else { 786 } else {
788 result = SavePageResult::STORE_FAILURE; 787 result = SavePageResult::STORE_FAILURE;
789 } 788 }
790 InformSavePageDone(callback, result, offline_page.client_id, 789 InformSavePageDone(callback, result, offline_page.client_id,
791 offline_page.offline_id); 790 offline_page.offline_id);
792 if (result == SavePageResult::SUCCESS) { 791 if (result == SavePageResult::SUCCESS) {
793 DeleteExistingPagesWithSameURL(offline_page); 792 DeleteExistingPagesWithSameURL(offline_page);
794 } else { 793 } else {
795 PostClearStorageIfNeededTask(); 794 PostClearStorageIfNeededTask(false /* delayed */);
796 } 795 }
797 796
798 DeletePendingArchiver(archiver); 797 DeletePendingArchiver(archiver);
799 for (Observer& observer : observers_) 798 for (Observer& observer : observers_)
800 observer.OfflinePageModelChanged(this); 799 observer.OfflinePageModelChanged(this);
801 } 800 }
802 801
803 void OfflinePageModelImpl::OnMarkPageAccesseDone( 802 void OfflinePageModelImpl::OnMarkPageAccesseDone(
804 const OfflinePageItem& offline_page_item, 803 const OfflinePageItem& offline_page_item,
805 std::unique_ptr<OfflinePagesUpdateResult> result) { 804 std::unique_ptr<OfflinePagesUpdateResult> result) {
806 // Update the item in the cache only upon success. 805 // Update the item in the cache only upon success.
807 if (result->updated_items.size() > 0) 806 if (result->updated_items.size() > 0)
808 offline_pages_[offline_page_item.offline_id] = offline_page_item; 807 offline_pages_[offline_page_item.offline_id] = offline_page_item;
809 808
810 // No need to fire OfflinePageModelChanged event since updating access info 809 // No need to fire OfflinePageModelChanged event since updating access info
811 // should not have any impact to the UI. 810 // should not have any impact to the UI.
812 } 811 }
813 812
814 void OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone( 813 void OfflinePageModelImpl::OnEnsureArchivesDirCreatedDone(
815 const base::TimeTicks& start_time) { 814 const base::TimeTicks& start_time) {
816 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime", 815 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ArchiveDirCreationTime",
817 base::TimeTicks::Now() - start_time); 816 base::TimeTicks::Now() - start_time);
818 817
818 store_->Initialize(base::Bind(&OfflinePageModelImpl::OnStoreInitialized,
819 weak_ptr_factory_.GetWeakPtr(), start_time));
820 }
821
822 void OfflinePageModelImpl::OnStoreInitialized(const base::TimeTicks& start_time,
823 StoreState state) {
824 if (state == StoreState::FAILED_RESET) {
825 CompleteLoad();
826 return;
827 }
828
829 if (state == StoreState::FAILED_LOADING) {
830 store_->Reset(base::Bind(&OfflinePageModelImpl::OnStoreInitialized,
831 weak_ptr_factory_.GetWeakPtr(), start_time));
832 return;
833 }
834
835 DCHECK_EQ(state, StoreState::LOADED);
819 store_->GetOfflinePages(base::Bind(&OfflinePageModelImpl::OnLoadDone, 836 store_->GetOfflinePages(base::Bind(&OfflinePageModelImpl::OnLoadDone,
820 weak_ptr_factory_.GetWeakPtr(), 837 weak_ptr_factory_.GetWeakPtr(),
821 start_time)); 838 start_time));
822 } 839 }
823 840
824 void OfflinePageModelImpl::OnLoadDone( 841 void OfflinePageModelImpl::OnLoadDone(
825 const base::TimeTicks& start_time, 842 const base::TimeTicks& start_time,
826 OfflinePageMetadataStore::LoadStatus load_status,
827 const std::vector<OfflinePageItem>& offline_pages) { 843 const std::vector<OfflinePageItem>& offline_pages) {
828 DCHECK(!is_loaded_); 844 DCHECK(!is_loaded_);
829 is_loaded_ = true;
830
831 // TODO(jianli): rebuild the store upon failure.
832
833 if (load_status == OfflinePageMetadataStore::LOAD_SUCCEEDED)
834 CacheLoadedData(offline_pages);
835 845
836 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ConstructionToLoadedEventTime", 846 UMA_HISTOGRAM_TIMES("OfflinePages.Model.ConstructionToLoadedEventTime",
837 base::TimeTicks::Now() - start_time); 847 base::TimeTicks::Now() - start_time);
838 848
839 // Create Storage Manager. 849 CacheLoadedData(offline_pages);
840 storage_manager_.reset(new OfflinePageStorageManager( 850 CompleteLoad();
841 this, GetPolicyController(), archive_manager_.get())); 851
852 // Ensure necessary cleanup operations are started.
853 CheckMetadataConsistency();
854 }
855
856 void OfflinePageModelImpl::CompleteLoad() {
857 is_loaded_ = true;
858
859 // All actions below are meant to be taken regardless of successful load of
860 // the store.
861
862 // Inform observers the load is done.
863 for (Observer& observer : observers_)
864 observer.OfflinePageModelLoaded(this);
842 865
843 // Run all the delayed tasks. 866 // Run all the delayed tasks.
844 for (const auto& delayed_task : delayed_tasks_) 867 for (const auto& delayed_task : delayed_tasks_)
845 delayed_task.Run(); 868 delayed_task.Run();
846 delayed_tasks_.clear(); 869 delayed_tasks_.clear();
847 870
848 for (Observer& observer : observers_) 871 // Clear storage.
849 observer.OfflinePageModelLoaded(this); 872 PostClearStorageIfNeededTask(true /* delayed */);
850
851 CheckMetadataConsistency();
852
853 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
854 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded,
855 weak_ptr_factory_.GetWeakPtr(),
856 base::Bind(&OfflinePageModelImpl::OnStorageCleared,
857 weak_ptr_factory_.GetWeakPtr())),
858 kStorageManagerStartingDelay);
859 } 873 }
860 874
861 void OfflinePageModelImpl::InformSavePageDone(const SavePageCallback& callback, 875 void OfflinePageModelImpl::InformSavePageDone(const SavePageCallback& callback,
862 SavePageResult result, 876 SavePageResult result,
863 const ClientId& client_id, 877 const ClientId& client_id,
864 int64_t offline_id) { 878 int64_t offline_id) {
865 ReportSavePageResultHistogramAfterSave(client_id, result); 879 ReportSavePageResultHistogramAfterSave(client_id, result);
866 archive_manager_->GetStorageStats( 880 archive_manager_->GetStorageStats(
867 base::Bind(&ReportStorageHistogramsAfterSave)); 881 base::Bind(&ReportStorageHistogramsAfterSave));
868 callback.Run(result, offline_id); 882 callback.Run(result, offline_id);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 page_ids_to_delete.push_back(item.offline_id); 921 page_ids_to_delete.push_back(item.offline_id);
908 DeletePagesByOfflineId( 922 DeletePagesByOfflineId(
909 page_ids_to_delete, 923 page_ids_to_delete,
910 base::Bind(&OfflinePageModelImpl::OnDeleteOldPagesWithSameURL, 924 base::Bind(&OfflinePageModelImpl::OnDeleteOldPagesWithSameURL,
911 weak_ptr_factory_.GetWeakPtr())); 925 weak_ptr_factory_.GetWeakPtr()));
912 } 926 }
913 927
914 void OfflinePageModelImpl::OnDeleteOldPagesWithSameURL( 928 void OfflinePageModelImpl::OnDeleteOldPagesWithSameURL(
915 DeletePageResult result) { 929 DeletePageResult result) {
916 // TODO(romax) Add UMAs for failure cases. 930 // TODO(romax) Add UMAs for failure cases.
917 PostClearStorageIfNeededTask(); 931 PostClearStorageIfNeededTask(false /* delayed */);
918 } 932 }
919 933
920 void OfflinePageModelImpl::DeletePendingArchiver( 934 void OfflinePageModelImpl::DeletePendingArchiver(
921 OfflinePageArchiver* archiver) { 935 OfflinePageArchiver* archiver) {
922 pending_archivers_.erase(std::find(pending_archivers_.begin(), 936 pending_archivers_.erase(std::find(pending_archivers_.begin(),
923 pending_archivers_.end(), archiver)); 937 pending_archivers_.end(), archiver));
924 } 938 }
925 939
926 void OfflinePageModelImpl::OnDeleteArchiveFilesDone( 940 void OfflinePageModelImpl::OnDeleteArchiveFilesDone(
927 const std::vector<int64_t>& offline_ids, 941 const std::vector<int64_t>& offline_ids,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 1060
1047 void OfflinePageModelImpl::CacheLoadedData( 1061 void OfflinePageModelImpl::CacheLoadedData(
1048 const std::vector<OfflinePageItem>& offline_pages) { 1062 const std::vector<OfflinePageItem>& offline_pages) {
1049 offline_pages_.clear(); 1063 offline_pages_.clear();
1050 for (const auto& offline_page : offline_pages) 1064 for (const auto& offline_page : offline_pages)
1051 offline_pages_[offline_page.offline_id] = offline_page; 1065 offline_pages_[offline_page.offline_id] = offline_page;
1052 } 1066 }
1053 1067
1054 void OfflinePageModelImpl::ClearStorageIfNeeded( 1068 void OfflinePageModelImpl::ClearStorageIfNeeded(
1055 const ClearStorageCallback& callback) { 1069 const ClearStorageCallback& callback) {
1070 // Create Storage Manager if necessary.
1071 if (!storage_manager_) {
1072 storage_manager_.reset(new OfflinePageStorageManager(
1073 this, GetPolicyController(), archive_manager_.get()));
1074 }
1056 storage_manager_->ClearPagesIfNeeded(callback); 1075 storage_manager_->ClearPagesIfNeeded(callback);
1057 } 1076 }
1058 1077
1059 void OfflinePageModelImpl::OnStorageCleared(size_t expired_page_count, 1078 void OfflinePageModelImpl::OnStorageCleared(size_t expired_page_count,
1060 ClearStorageResult result) { 1079 ClearStorageResult result) {
1061 UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearStorageResult", 1080 UMA_HISTOGRAM_ENUMERATION("OfflinePages.ClearStorageResult",
1062 static_cast<int>(result), 1081 static_cast<int>(result),
1063 static_cast<int>(ClearStorageResult::RESULT_COUNT)); 1082 static_cast<int>(ClearStorageResult::RESULT_COUNT));
1064 if (expired_page_count > 0) { 1083 if (expired_page_count > 0) {
1065 UMA_HISTOGRAM_COUNTS("OfflinePages.ExpirePage.BatchSize", 1084 UMA_HISTOGRAM_COUNTS("OfflinePages.ExpirePage.BatchSize",
1066 static_cast<int32_t>(expired_page_count)); 1085 static_cast<int32_t>(expired_page_count));
1067 } 1086 }
1068 } 1087 }
1069 1088
1070 void OfflinePageModelImpl::PostClearStorageIfNeededTask() { 1089 void OfflinePageModelImpl::PostClearStorageIfNeededTask(bool delayed) {
1071 base::ThreadTaskRunnerHandle::Get()->PostTask( 1090 base::TimeDelta delay =
1091 delayed ? kStorageManagerStartingDelay : base::TimeDelta();
1092 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1072 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded, 1093 FROM_HERE, base::Bind(&OfflinePageModelImpl::ClearStorageIfNeeded,
1073 weak_ptr_factory_.GetWeakPtr(), 1094 weak_ptr_factory_.GetWeakPtr(),
1074 base::Bind(&OfflinePageModelImpl::OnStorageCleared, 1095 base::Bind(&OfflinePageModelImpl::OnStorageCleared,
1075 weak_ptr_factory_.GetWeakPtr()))); 1096 weak_ptr_factory_.GetWeakPtr())),
1097 delay);
1076 } 1098 }
1077 1099
1078 bool OfflinePageModelImpl::IsRemovedOnCacheReset( 1100 bool OfflinePageModelImpl::IsRemovedOnCacheReset(
1079 const OfflinePageItem& offline_page) const { 1101 const OfflinePageItem& offline_page) const {
1080 return policy_controller_->IsRemovedOnCacheReset( 1102 return policy_controller_->IsRemovedOnCacheReset(
1081 offline_page.client_id.name_space); 1103 offline_page.client_id.name_space);
1082 } 1104 }
1083 1105
1084 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) { 1106 void OfflinePageModelImpl::RunWhenLoaded(const base::Closure& task) {
1085 if (!is_loaded_) { 1107 if (!is_loaded_) {
1086 delayed_tasks_.push_back(task); 1108 delayed_tasks_.push_back(task);
1087 return; 1109 return;
1088 } 1110 }
1089 1111
1090 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task); 1112 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, task);
1091 } 1113 }
1092 1114
1093 base::Time OfflinePageModelImpl::GetCurrentTime() const { 1115 base::Time OfflinePageModelImpl::GetCurrentTime() const {
1094 return testing_clock_ ? testing_clock_->Now() : base::Time::Now(); 1116 return testing_clock_ ? testing_clock_->Now() : base::Time::Now();
1095 } 1117 }
1096 1118
1097 } // namespace offline_pages 1119 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698