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: 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 base::Time now = base::Time::Now();
69 statistics_.num_errors_on_evicting_origin); 69 UMA_HISTOGRAM_TIMES("Quota.TimeSpentToAEvictionRound",
70 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnGettingUsageAndQuota", 70 now - round_statistics_.start_time);
71 statistics_.num_errors_on_getting_usage_and_quota); 71 if (!time_of_end_of_last_round_.is_null())
72 UMA_HISTOGRAM_COUNTS("Quota.EvictedOrigins", 72 UMA_HISTOGRAM_MINUTES("Quota.TimeDeltaOfEvictionRounds",
73 statistics_.num_evicted_origins); 73 now - time_of_end_of_last_round_);
74 UMA_HISTOGRAM_COUNTS("Quota.EvictionRounds", 74 UMA_HISTOGRAM_MBYTES("Quota.AmountOfOverageOfTemporaryGlobalStorage",
75 statistics_.num_eviction_rounds); 75 round_statistics_.amount_of_usage_overage);
76 UMA_HISTOGRAM_COUNTS("Quota.SkippedEvictionRounds", 76 UMA_HISTOGRAM_MBYTES("Quota.AmountOfShortageOfDiskspace",
77 statistics_.num_skipped_eviction_rounds); 77 round_statistics_.amount_of_diskspace_shortage);
78 UMA_HISTOGRAM_MBYTES("Quota.EvictedBytesPerRound",
79 round_statistics_.usage_on_beginning_of_round -
80 round_statistics_.usage_on_end_of_round);
81 UMA_HISTOGRAM_COUNTS("Quota.NumberOfEvictedOriginsPerRound",
82 round_statistics_.num_evicted_origins);
83 round_statistics_ = EvictionRoundStatistics();
84 }
78 85
79 statistics_ = Statistics(); 86 void QuotaTemporaryStorageEvictor::ReportPerHourHistogram() {
87 Statistics stats(statistics_);
88 stats -= reported_hourly_statistics_;
89 reported_hourly_statistics_ = statistics_;
90
91 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnEvictingOriginPerHour",
92 stats.num_errors_on_evicting_origin);
93 UMA_HISTOGRAM_COUNTS("Quota.ErrorsOnGettingUsageAndQuotaPerHour",
94 stats.num_errors_on_getting_usage_and_quota);
95 UMA_HISTOGRAM_COUNTS("Quota.EvictedOriginsPerHour",
96 stats.num_evicted_origins);
97 UMA_HISTOGRAM_COUNTS("Quota.EvictionRoundsPerHour",
98 stats.num_eviction_rounds);
99 UMA_HISTOGRAM_COUNTS("Quota.SkippedEvictionRoundsPerHour",
100 stats.num_skipped_eviction_rounds);
101 }
102
103 void QuotaTemporaryStorageEvictor::OnEvictionRoundStarted() {
104 if (round_statistics_.started)
105 return;
106 round_statistics_.started = true;
107 round_statistics_.start_time = base::Time::Now();
108 ++statistics_.num_eviction_rounds;
109 }
110
111 void QuotaTemporaryStorageEvictor::OnEvictionRoundFinished() {
112 // Check if skipped round
113 if (round_statistics_.num_evicted_origins) {
114 ReportPerRoundHistogram();
115 time_of_last_nonskipped_round_ = base::Time::Now();
116 } else {
117 ++statistics_.num_skipped_eviction_rounds;
118 round_statistics_ = EvictionRoundStatistics();
119 }
80 } 120 }
81 121
82 void QuotaTemporaryStorageEvictor::Start() { 122 void QuotaTemporaryStorageEvictor::Start() {
83 DCHECK(CalledOnValidThread()); 123 DCHECK(CalledOnValidThread());
84 StartEvictionTimerWithDelay(0); 124 StartEvictionTimerWithDelay(0);
85 125
86 if (histogram_timer_.IsRunning()) 126 if (histogram_timer_.IsRunning())
87 return; 127 return;
88 histogram_timer_.Start(kHistogramReportInterval, this, 128 histogram_timer_.Start(kHistogramReportInterval, this,
89 &QuotaTemporaryStorageEvictor::ReportHistogram); 129 &QuotaTemporaryStorageEvictor::ReportPerHourHistogram);
90 } 130 }
91 131
92 void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) { 132 void QuotaTemporaryStorageEvictor::StartEvictionTimerWithDelay(int delay_ms) {
93 if (eviction_timer_.IsRunning()) 133 if (eviction_timer_.IsRunning())
94 return; 134 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, 135 eviction_timer_.Start(base::TimeDelta::FromMilliseconds(delay_ms), this,
100 &QuotaTemporaryStorageEvictor::ConsiderEviction); 136 &QuotaTemporaryStorageEvictor::ConsiderEviction);
101 } 137 }
102 138
103 void QuotaTemporaryStorageEvictor::ConsiderEviction() { 139 void QuotaTemporaryStorageEvictor::ConsiderEviction() {
140 OnEvictionRoundStarted();
141
104 // Get usage and disk space, then continue. 142 // Get usage and disk space, then continue.
105 quota_eviction_handler_->GetUsageAndQuotaForEviction(callback_factory_. 143 quota_eviction_handler_->GetUsageAndQuotaForEviction(callback_factory_.
106 NewCallback( 144 NewCallback(
107 &QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction)); 145 &QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction));
108 } 146 }
109 147
110 void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction( 148 void QuotaTemporaryStorageEvictor::OnGotUsageAndQuotaForEviction(
111 QuotaStatusCode status, 149 QuotaStatusCode status,
112 int64 usage, 150 int64 usage,
113 int64 unlimited_usage, 151 int64 unlimited_usage,
114 int64 quota, 152 int64 quota,
115 int64 available_disk_space) { 153 int64 available_disk_space) {
116 DCHECK(CalledOnValidThread()); 154 DCHECK(CalledOnValidThread());
117 DCHECK_GE(usage, unlimited_usage); // unlimited_usage is a subset of usage 155 DCHECK_GE(usage, unlimited_usage); // unlimited_usage is a subset of usage
118 156
119 usage -= unlimited_usage; 157 usage -= unlimited_usage;
120 158
121 if (status != kQuotaStatusOk) 159 if (status != kQuotaStatusOk)
122 ++statistics_.num_errors_on_getting_usage_and_quota; 160 ++statistics_.num_errors_on_getting_usage_and_quota;
123 161
124 int64 amount_to_evict = std::max( 162 int64 amount_of_usage_overage = std::max(
125 usage - static_cast<int64>(quota * kUsageRatioToStartEviction), 163 static_cast<int64>(0),
164 usage - static_cast<int64>(quota * kUsageRatioToStartEviction));
165 round_statistics_.put_usage_overage(amount_of_usage_overage);
166
167 int64 amount_of_diskspace_shortage = std::max(
168 static_cast<int64>(0),
126 min_available_disk_space_to_start_eviction_ - available_disk_space); 169 min_available_disk_space_to_start_eviction_ - available_disk_space);
170 round_statistics_.put_diskspace_shortage(amount_of_diskspace_shortage);
171 round_statistics_.put_usage(usage);
172
173 int64 amount_to_evict = std::max(amount_of_usage_overage,
174 amount_of_diskspace_shortage);
127 if (status == kQuotaStatusOk && amount_to_evict > 0) { 175 if (status == kQuotaStatusOk && amount_to_evict > 0) {
128 // Space is getting tight. Get the least recently used origin and continue. 176 // 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, 177 // TODO(michaeln): if the reason for eviction is low physical disk space,
130 // make 'unlimited' origins subject to eviction too. 178 // 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, 179 quota_eviction_handler_->GetLRUOrigin(kStorageTypeTemporary,
139 callback_factory_.NewCallback( 180 callback_factory_.NewCallback(
140 &QuotaTemporaryStorageEvictor::OnGotLRUOrigin)); 181 &QuotaTemporaryStorageEvictor::OnGotLRUOrigin));
141 } else if (repeated_eviction_) { 182 } else {
142 // No action required, sleep for a while and check again later. 183 if (repeated_eviction_) {
143 if (num_evicted_origins_in_round_ == 0) { 184 // No action required, sleep for a while and check again later.
144 ++statistics_.num_skipped_eviction_rounds; 185 if (statistics_.num_errors_on_getting_usage_and_quota <
145 } else if (usage_on_beginning_of_round_ >= 0) { 186 kThresholdOfErrorsToStopEviction) {
146 int64 evicted_bytes = usage_on_beginning_of_round_ - usage; 187 StartEvictionTimerWithDelay(interval_ms_);
147 base::Time now = base::Time::Now(); 188 } else {
148 UMA_HISTOGRAM_MBYTES("Quota.EvictedBytesPerRound", evicted_bytes); 189 // TODO(dmikurube): Try restarting eviction after a while.
149 UMA_HISTOGRAM_COUNTS("Quota.NumberOfEvictedOriginsPerRound", 190 LOG(WARNING) << "Stopped eviction of temporary storage due to errors "
150 num_evicted_origins_in_round_); 191 "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 } 192 }
157 time_of_end_of_last_round_ = now;
158 } 193 }
159 if (statistics_.num_errors_on_getting_usage_and_quota < 194 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 } 195 }
168 196
169 // TODO(dmikurube): Add error handling for the case status != kQuotaStatusOk. 197 // TODO(dmikurube): Add error handling for the case status != kQuotaStatusOk.
170 } 198 }
171 199
172 void QuotaTemporaryStorageEvictor::OnGotLRUOrigin(const GURL& origin) { 200 void QuotaTemporaryStorageEvictor::OnGotLRUOrigin(const GURL& origin) {
173 DCHECK(CalledOnValidThread()); 201 DCHECK(CalledOnValidThread());
174 202
175 if (origin.is_empty()) { 203 if (origin.is_empty()) {
176 if (repeated_eviction_) 204 if (repeated_eviction_)
177 StartEvictionTimerWithDelay(interval_ms_); 205 StartEvictionTimerWithDelay(interval_ms_);
206 OnEvictionRoundFinished();
178 return; 207 return;
179 } 208 }
180 209
181 quota_eviction_handler_->EvictOriginData(origin, kStorageTypeTemporary, 210 quota_eviction_handler_->EvictOriginData(origin, kStorageTypeTemporary,
182 callback_factory_.NewCallback( 211 callback_factory_.NewCallback(
183 &QuotaTemporaryStorageEvictor::OnEvictionComplete)); 212 &QuotaTemporaryStorageEvictor::OnEvictionComplete));
184 } 213 }
185 214
186 void QuotaTemporaryStorageEvictor::OnEvictionComplete( 215 void QuotaTemporaryStorageEvictor::OnEvictionComplete(
187 QuotaStatusCode status) { 216 QuotaStatusCode status) {
188 DCHECK(CalledOnValidThread()); 217 DCHECK(CalledOnValidThread());
189 218
190 // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is 219 // Just calling ConsiderEviction() or StartEvictionTimerWithDelay() here is
191 // ok. No need to deal with the case that all of the Delete operations fail 220 // 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 221 // 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 222 // origin permanently. The evictor skips origins which had deletion errors
194 // a few times. 223 // a few times.
195 224
196 if (status == kQuotaStatusOk) { 225 if (status == kQuotaStatusOk) {
197 ++statistics_.num_evicted_origins; 226 ++statistics_.num_evicted_origins;
198 ++num_evicted_origins_in_round_; 227 ++round_statistics_.num_evicted_origins;
199 // We many need to get rid of more space so reconsider immediately. 228 // We many need to get rid of more space so reconsider immediately.
200 ConsiderEviction(); 229 ConsiderEviction();
201 } else { 230 } else {
202 ++statistics_.num_errors_on_evicting_origin; 231 ++statistics_.num_errors_on_evicting_origin;
203 if (repeated_eviction_) { 232 if (repeated_eviction_) {
204 // Sleep for a while and retry again until we see too many errors. 233 // Sleep for a while and retry again until we see too many errors.
205 StartEvictionTimerWithDelay(interval_ms_); 234 StartEvictionTimerWithDelay(interval_ms_);
206 } 235 }
236 OnEvictionRoundFinished();
207 } 237 }
208 } 238 }
209 239
210 } // namespace quota 240 } // namespace quota
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698