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

Side by Side Diff: webkit/quota/quota_temporary_storage_evictor.cc

Issue 7582027: Refine UMA stats of QuotaTemporaryStorageEvictor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: '' Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "webkit/quota/quota_temporary_storage_evictor.h" 5 #include "webkit/quota/quota_temporary_storage_evictor.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "googleurl/src/gurl.h" 8 #include "googleurl/src/gurl.h"
9 #include "webkit/quota/quota_manager.h" 9 #include "webkit/quota/quota_manager.h"
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 (*statistics)["errors-on-getting-usage-and-quota"] = 57 (*statistics)["errors-on-getting-usage-and-quota"] =
58 statistics_.num_errors_on_getting_usage_and_quota; 58 statistics_.num_errors_on_getting_usage_and_quota;
59 (*statistics)["evicted-origins"] = 59 (*statistics)["evicted-origins"] =
60 statistics_.num_evicted_origins; 60 statistics_.num_evicted_origins;
61 (*statistics)["eviction-rounds"] = 61 (*statistics)["eviction-rounds"] =
62 statistics_.num_eviction_rounds; 62 statistics_.num_eviction_rounds;
63 (*statistics)["skipped-eviction-rounds"] = 63 (*statistics)["skipped-eviction-rounds"] =
64 statistics_.num_skipped_eviction_rounds; 64 statistics_.num_skipped_eviction_rounds;
65 } 65 }
66 66
67 void QuotaTemporaryStorageEvictor::ReportHistogram() { 67 void QuotaTemporaryStorageEvictor::ReportPerRoundHistogram() {
68 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnEvictingOrigin", 68 DCHECK(round_statistics_.in_round);
69 statistics_.num_errors_on_evicting_origin); 69 DCHECK(round_statistics_.is_initialized);
70 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnGettingUsageAndQuota",
71 statistics_.num_errors_on_getting_usage_and_quota);
72 UMA_HISTOGRAM_COUNTS("Quota.EvictedOrigins",
73 statistics_.num_evicted_origins);
74 UMA_HISTOGRAM_COUNTS("Quota.EvictionRounds",
75 statistics_.num_eviction_rounds);
76 UMA_HISTOGRAM_COUNTS("Quota.SkippedEvictionRounds",
77 statistics_.num_skipped_eviction_rounds);
78 70
79 statistics_ = Statistics(); 71 base::Time now = base::Time::Now();
72 UMA_HISTOGRAM_TIMES("Quota.TimeSpentToAEvictionRound",
73 now - round_statistics_.start_time);
74 if (!time_of_end_of_last_round_.is_null())
75 UMA_HISTOGRAM_MINUTES("Quota.TimeDeltaOfEvictionRounds",
76 now - time_of_end_of_last_round_);
77 UMA_HISTOGRAM_MBYTES("Quota.UsageOverageOfTemporaryGlobalStorage",
78 round_statistics_.usage_overage_at_round);
79 UMA_HISTOGRAM_MBYTES("Quota.DiskspaceShortage",
80 round_statistics_.diskspace_shortage_at_round);
81 UMA_HISTOGRAM_MBYTES("Quota.EvictedBytesPerRound",
82 round_statistics_.usage_on_beginning_of_round -
83 round_statistics_.usage_on_end_of_round);
84 UMA_HISTOGRAM_COUNTS("Quota.NumberOfEvictedOriginsPerRound",
85 round_statistics_.num_evicted_origins_in_round);
86 }
87
88 void QuotaTemporaryStorageEvictor::ReportPerHourHistogram() {
89 Statistics stats(statistics_);
Dai Mikurube (NOT FULLTIME) 2011/08/12 07:32:39 Can we have more appropriate name for this variabl
tzik 2011/08/16 04:31:54 Done.
90 stats.subtract_assign(previous_statistics_);
91 previous_statistics_ = statistics_;
92
93 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnEvictingOriginPerHour",
94 stats.num_errors_on_evicting_origin);
95 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnGettingUsageAndQuotaPerHour",
96 stats.num_errors_on_getting_usage_and_quota);
97 UMA_HISTOGRAM_COUNTS("Quota.EvictedOriginsPerHour",
98 stats.num_evicted_origins);
99 UMA_HISTOGRAM_COUNTS("Quota.EvictionRoundsPerHour",
100 stats.num_eviction_rounds);
101 UMA_HISTOGRAM_COUNTS("Quota.SkippedEvictionRoundsPerHour",
102 stats.num_skipped_eviction_rounds);
103 }
104
105 void QuotaTemporaryStorageEvictor::OnEvictionRoundStarted() {
106 if (round_statistics_.in_round)
107 return;
108 round_statistics_.in_round = true;
109 round_statistics_.start_time = base::Time::Now();
110 ++statistics_.num_eviction_rounds;
111 }
112
113 void QuotaTemporaryStorageEvictor::OnEvictionRoundFinished() {
114 // Check if skipped round
115 if (round_statistics_.num_evicted_origins_in_round) {
116 ReportPerRoundHistogram();
117 time_of_end_of_last_nonskipped_round_ = base::Time::Now();
118 } else {
119 ++statistics_.num_skipped_eviction_rounds;
120 }
121 // Reset stats for next round.
122 round_statistics_ = EvictionRoundStatistics();
80 } 123 }
81 124
82 void QuotaTemporaryStorageEvictor::Start() { 125 void QuotaTemporaryStorageEvictor::Start() {
83 DCHECK(CalledOnValidThread()); 126 DCHECK(CalledOnValidThread());
84 StartEvictionTimerWithDelay(0); 127 StartEvictionTimerWithDelay(0);
85 128
86 if (histogram_timer_.IsRunning()) 129 if (histogram_timer_.IsRunning())
87 return; 130 return;
88 histogram_timer_.Start(kHistogramReportInterval, this, 131 histogram_timer_.Start(kHistogramReportInterval, this,
89 &QuotaTemporaryStorageEvictor::ReportHistogram); 132 &QuotaTemporaryStorageEvictor::ReportPerHourHistogram);
90 } 133 }
91 134
92 void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) { 135 void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) {
93 if (eviction_timer_.IsRunning()) 136 if (eviction_timer_.IsRunning())
94 return; 137 return;
95 num_evicted_origins_in_round_ = 0;
96 usage_on_beginning_of_round_ = -1;
97 time_of_beginning_of_round_ = base::Time::Now();
98 ++statistics_.num_eviction_rounds;
99 eviction_timer_.Start(base::TimeDelta::FromMilliseconds(delay_ms), this, 138 eviction_timer_.Start(base::TimeDelta::FromMilliseconds(delay_ms), this,
100 &QuotaTemporaryStorageEvictor::ConsiderEviction); 139 &QuotaTemporaryStorageEvictor::ConsiderEviction);
101 } 140 }
102 141
103 void QuotaTemporaryStorageEvictor::ConsiderEviction() { 142 void QuotaTemporaryStorageEvictor::ConsiderEviction() {
143 OnEvictionRoundStarted();
144
104 // Get usage and disk space, then continue. 145 // Get usage and disk space, then continue.
105 quota_eviction_handler_->GetUsageAndQuotaForEviction(callback_factory_. 146 quota_eviction_handler_->GetUsageAndQuotaForEviction(callback_factory_.
106 NewCallback( 147 NewCallback(
107 &QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction)); 148 &QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction));
108 } 149 }
109 150
110 void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction( 151 void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction(
111 QuotaStatusCode status, 152 QuotaStatusCode status,
112 int64 usage, 153 int64 usage,
113 int64 unlimited_usage, 154 int64 unlimited_usage,
114 int64 quota, 155 int64 quota,
115 int64 available_disk_space) { 156 int64 available_disk_space) {
116 DCHECK(CalledOnValidThread()); 157 DCHECK(CalledOnValidThread());
117 DCHECK_GE(usage, unlimited_usage); // unlimited_usage is a subset of usage 158 DCHECK_GE(usage, unlimited_usage); // unlimited_usage is a subset of usage
118 159
119 usage -= unlimited_usage; 160 usage -= unlimited_usage;
120 161
121 if (status != kQuotaStatusOk) 162 if (status != kQuotaStatusOk)
122 ++statistics_.num_errors_on_getting_usage_and_quota; 163 ++statistics_.num_errors_on_getting_usage_and_quota;
123 164
124 int64 amount_to_evict = std::max( 165 int64 usage_overage = std::max(
125 usage - static_cast<int64>(quota * kUsageRatioToStartEviction), 166 static_cast<int64>(0),
167 usage - static_cast<int64>(quota * kUsageRatioToStartEviction));
168
169 int64 diskspace_shortage = std::max(
170 static_cast<int64>(0),
126 min_available_disk_space_to_start_eviction_ - available_disk_space); 171 min_available_disk_space_to_start_eviction_ - available_disk_space);
172
173 if (!round_statistics_.is_initialized) {
174 round_statistics_.usage_overage_at_round = usage_overage;
175 round_statistics_.diskspace_shortage_at_round = diskspace_shortage;
176 round_statistics_.usage_on_beginning_of_round = usage;
177 round_statistics_.is_initialized = true;
178 }
179 round_statistics_.usage_on_end_of_round = usage;
180
181 int64 amount_to_evict = std::max(usage_overage, diskspace_shortage);
127 if (status == kQuotaStatusOk && amount_to_evict > 0) { 182 if (status == kQuotaStatusOk && amount_to_evict > 0) {
128 // Space is getting tight. Get the least recently used origin and continue. 183 // Space is getting tight. Get the least recently used origin and continue.
129 // TODO(michaeln): if the reason for eviction is low physical disk space, 184 // TODO(michaeln): if the reason for eviction is low physical disk space,
130 // make 'unlimited' origins subject to eviction too. 185 // make 'unlimited' origins subject to eviction too.
131
132 if (usage_on_beginning_of_round_ < 0) {
133 usage_on_beginning_of_round_ = usage;
134 UMA_HISTOGRAM_MBYTES("Quota.TemporaryStorageSizeToEvict",
135 amount_to_evict);
136 }
137
138 quota_eviction_handler_->GetLRUOrigin(kStorageTypeTemporary, 186 quota_eviction_handler_->GetLRUOrigin(kStorageTypeTemporary,
139 callback_factory_.NewCallback( 187 callback_factory_.NewCallback(
140 &QuotaTemporaryStorageEvictor::OnGotLRUOrigin)); 188 &QuotaTemporaryStorageEvictor::OnGotLRUOrigin));
141 } else if (repeated_eviction_) { 189 } else {
142 // No action required, sleep for a while and check again later. 190 if (repeated_eviction_) {
143 if (num_evicted_origins_in_round_ == 0) { 191 // No action required, sleep for a while and check again later.
144 ++statistics_.num_skipped_eviction_rounds; 192 if (statistics_.num_errors_on_getting_usage_and_quota <
145 } else if (usage_on_beginning_of_round_ >= 0) { 193 kThresholdOfErrorsToStopEviction) {
146 int64 evicted_bytes = usage_on_beginning_of_round_ - usage; 194 StartEvictionTimerWithDelay(interval_ms_);
147 base::Time now = base::Time::Now(); 195 } else {
148 UMA_HISTOGRAM_MBYTES("Quota.EvictedBytesPerRound", evicted_bytes); 196 // TODO(dmikurube): Try restarting eviction after a while.
149 UMA_HISTOGRAM_COUNTS("Quota.NumberOfEvictedOriginsPerRound", 197 LOG(WARNING) << "Stopped eviction of temporary storage due to errors "
150 num_evicted_origins_in_round_); 198 "in GetUsageAndQuotaForEviction.";
151 UMA_HISTOGRAM_TIMES("Quota.TimeSpentToAEvictionRound",
152 now - time_of_beginning_of_round_);
153 if (!time_of_end_of_last_round_.is_null()) {
154 UMA_HISTOGRAM_MINUTES("Quota.TimeDeltaOfEvictionRounds",
155 now - time_of_end_of_last_round_);
156 } 199 }
157 time_of_end_of_last_round_ = now;
158 } 200 }
159 if (statistics_.num_errors_on_getting_usage_and_quota < 201 OnEvictionRoundFinished();
160 kThresholdOfErrorsToStopEviction) {
161 StartEvictionTimerWithDelay(interval_ms_);
162 } else {
163 // TODO(dmikurube): Try restarting eviction after a while.
164 LOG(WARNING) << "Stopped eviction of temporary storage due to errors "
165 "in GetUsageAndQuotaForEviction.";
166 }
167 } 202 }
168 203
169 // TODO(dmikurube): Add error handling for the case status != kQuotaStatusOk. 204 // TODO(dmikurube): Add error handling for the case status != kQuotaStatusOk.
170 } 205 }
171 206
172 void QuotaTemporaryStorageEvictor::OnGotLRUOrigin(const GURL& origin) { 207 void QuotaTemporaryStorageEvictor::OnGotLRUOrigin(const GURL& origin) {
173 DCHECK(CalledOnValidThread()); 208 DCHECK(CalledOnValidThread());
174 209
175 if (origin.is_empty()) { 210 if (origin.is_empty()) {
176 if (repeated_eviction_) 211 if (repeated_eviction_)
177 StartEvictionTimerWithDelay(interval_ms_); 212 StartEvictionTimerWithDelay(interval_ms_);
213 OnEvictionRoundFinished();
178 return; 214 return;
179 } 215 }
180 216
181 quota_eviction_handler_->EvictOriginData(origin, kStorageTypeTemporary, 217 quota_eviction_handler_->EvictOriginData(origin, kStorageTypeTemporary,
182 callback_factory_.NewCallback( 218 callback_factory_.NewCallback(
183 &QuotaTemporaryStorageEvictor::OnEvictionComplete)); 219 &QuotaTemporaryStorageEvictor::OnEvictionComplete));
184 } 220 }
185 221
186 void QuotaTemporaryStorageEvictor::OnEvictionComplete( 222 void QuotaTemporaryStorageEvictor::OnEvictionComplete(
187 QuotaStatusCode status) { 223 QuotaStatusCode status) {
188 DCHECK(CalledOnValidThread()); 224 DCHECK(CalledOnValidThread());
189 225
190 // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is 226 // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is
191 // ok. No need to deal with the case that all of the Delete operations fail 227 // ok. No need to deal with the case that all of the Delete operations fail
192 // for a certain origin. It doesn't result in trying to evict the same 228 // for a certain origin. It doesn't result in trying to evict the same
193 // origin permanently. The evictor skips origins which had deletion errors 229 // origin permanently. The evictor skips origins which had deletion errors
194 // a few times. 230 // a few times.
195 231
196 if (status == kQuotaStatusOk) { 232 if (status == kQuotaStatusOk) {
197 ++statistics_.num_evicted_origins; 233 ++statistics_.num_evicted_origins;
198 ++num_evicted_origins_in_round_; 234 ++round_statistics_.num_evicted_origins_in_round;
199 // We many need to get rid of more space so reconsider immediately. 235 // We many need to get rid of more space so reconsider immediately.
200 ConsiderEviction(); 236 ConsiderEviction();
201 } else { 237 } else {
202 ++statistics_.num_errors_on_evicting_origin; 238 ++statistics_.num_errors_on_evicting_origin;
203 if (repeated_eviction_) { 239 if (repeated_eviction_) {
204 // Sleep for a while and retry again until we see too many errors. 240 // Sleep for a while and retry again until we see too many errors.
205 StartEvictionTimerWithDelay(interval_ms_); 241 StartEvictionTimerWithDelay(interval_ms_);
206 } 242 }
243 OnEvictionRoundFinished();
207 } 244 }
208 } 245 }
209 246
210 } // namespace quota 247 } // namespace quota
OLDNEW
« no previous file with comments | « webkit/quota/quota_temporary_storage_evictor.h ('k') | webkit/quota/quota_temporary_storage_evictor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698