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

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