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

Unified Diff: components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.cc

Issue 1127893002: Add DataReductionProxyExperimentsStats and UMA for measuring potentially non-compressed bytes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sclittle CR comments + rebase Created 5 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.cc
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0ba22234b90db5aaefa2098703f24254f24807ac
--- /dev/null
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.cc
@@ -0,0 +1,287 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_experiments_stats.h"
+
+#include "base/logging.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
+#include "components/variations/variations_associated_data.h"
+#include "net/url_request/url_request.h"
+
+namespace {
+
+// The trial group prefix for which an experiment is considered enabled.
+const char kEnabled[] = "Enabled";
+
+// The number of config fetch variations supported. Must match the number of
+// suffixes in histograms.xml.
+const int kConfigFetchGroups = 10;
+
+// The minimum interval (in seconds) at which the config retrieval can occur.
+const int kConfigFetchMinimumIntervalSeconds = 300;
+
+// The default latency base for retrieving the config.
+const int kConfigFetchDefaultRoundtripMillisecondsBase = 100;
+
+// The default latency base for retrieving the config.
+const double kConfigFetchDefaultRoundtripMultiplier = 1.0;
+
+// The default latency base for retrieving the config.
+const int kConfigFetchDefaultRoundtripMillisecondsIncrement = 100;
+
+// The simulated default expiration for retrieving the config.
+const int kConfigFetchDefaultExpirationSeconds = 24 * 60 * 60;
+
+base::HistogramBase* GetHistogramWithSuffix(const char* histogram, int suffix) {
+ std::string full_histogram_name = histogram + base::IntToString(suffix);
+ return base::Histogram::FactoryGet(
+ full_histogram_name, 1, 1000000, 50,
+ base::HistogramBase::kUmaTargetedHistogramFlag);
+}
+
+} // namespace
+
+namespace data_reduction_proxy {
+
+namespace experiments {
+
+const char kConfigFetchTrialGroup[] = "DataReductionProxyConfigFetchBytes";
+
+const char kConfigRoundtripMillisecondsBaseParam[] =
+ "config_roundtrip_milliseconds_base";
+
+const char kConfigRoundtripMultiplierParam[] = "config_roundtrip_multiplier";
+
+const char kConfigRoundtripMillisecondsIncrementParam[] =
+ "config_roundtrip_milliseconds_increment";
+
+const char kConfigExpirationSecondsParam[] = "config_expiration_seconds";
+
+const char kConfigAlwaysStaleParam[] = "always_stale";
+
+const int kConfigFetchBufferSeconds = 300;
+
+} // namespace experiments
+
+// static
+scoped_ptr<DataReductionProxyExperimentsStats::ConfigRetrievalParams>
+DataReductionProxyExperimentsStats::ConfigRetrievalParams::Create(
+ PrefService* pref_service) {
+ base::StringPiece group =
+ base::FieldTrialList::FindFullName(experiments::kConfigFetchTrialGroup);
+ if (!group.starts_with(kEnabled))
+ return scoped_ptr<
+ DataReductionProxyExperimentsStats::ConfigRetrievalParams>();
+
+ std::string config_always_stale_value =
+ variations::GetVariationParamValue(experiments::kConfigFetchTrialGroup,
+ experiments::kConfigAlwaysStaleParam);
+ int config_always_stale;
+ int64 config_update_time;
+ if (!config_always_stale_value.empty() &&
+ base::StringToInt(config_always_stale_value, &config_always_stale) &&
+ config_always_stale == 1) {
+ config_update_time = 0;
+ } else {
+ config_update_time =
+ pref_service->GetInt64(prefs::kSimulatedConfigExpireTime);
+ }
+
+ std::string config_expiration_seconds_value =
+ variations::GetVariationParamValue(
+ experiments::kConfigFetchTrialGroup,
+ experiments::kConfigExpirationSecondsParam);
+ int64 config_expiration_interval_seconds;
+ if (config_expiration_seconds_value.empty() ||
+ !base::StringToInt64(config_expiration_seconds_value,
+ &config_expiration_interval_seconds))
+ config_expiration_interval_seconds = kConfigFetchDefaultExpirationSeconds;
+ base::TimeDelta config_expiration_interval =
+ base::TimeDelta::FromSeconds(config_expiration_interval_seconds);
+
+ std::vector<Variation> variations;
+ base::Time now = base::Time::Now();
+ base::Time config_expiration =
+ base::Time::FromInternalValue(config_update_time);
+ if (now > config_expiration) {
sclittle 2015/05/12 19:32:25 Could some of this be pulled out into helper funct
jeremyim 2015/05/12 20:38:29 Done.
+ config_expiration = now + config_expiration_interval;
+ std::string roundtrip_milliseconds_base =
+ variations::GetVariationParamValue(
+ experiments::kConfigFetchTrialGroup,
+ experiments::kConfigRoundtripMillisecondsBaseParam);
+ int64 config_roundtrip_milliseconds;
+ if (roundtrip_milliseconds_base.empty() ||
+ !base::StringToInt64(roundtrip_milliseconds_base,
+ &config_roundtrip_milliseconds) ||
+ config_roundtrip_milliseconds < 0)
+ config_roundtrip_milliseconds =
+ kConfigFetchDefaultRoundtripMillisecondsBase;
+ std::string roundtrip_multiplier_value;
+ double config_roundtrip_multiplier;
+ if (roundtrip_multiplier_value.empty() ||
sclittle 2015/05/12 19:32:25 |roundtrip_multiplier_value| doesn't appear to be
jeremyim 2015/05/12 20:38:29 Done.
+ !base::StringToDouble(roundtrip_multiplier_value,
+ &config_roundtrip_multiplier) ||
+ config_roundtrip_multiplier < 1.0) {
+ config_roundtrip_multiplier = kConfigFetchDefaultRoundtripMultiplier;
+ }
+ std::string roundtrip_milliseconds_increment_value;
sclittle 2015/05/12 19:32:25 Same here, this variable doesn't get assigned anyw
jeremyim 2015/05/12 20:38:29 Done.
+ int64 roundtrip_milliseconds_increment;
+ if (roundtrip_milliseconds_increment_value.empty() ||
+ !base::StringToInt64(roundtrip_milliseconds_increment_value,
+ &roundtrip_milliseconds_increment) ||
+ roundtrip_milliseconds_increment < 0) {
+ roundtrip_milliseconds_increment =
+ kConfigFetchDefaultRoundtripMillisecondsIncrement;
+ }
+
+ int params_index = 0;
+ do {
+ base::Time config_retrieved = now + base::TimeDelta::FromMilliseconds(
+ config_roundtrip_milliseconds);
+ variations.push_back(Variation(params_index, config_retrieved));
+ config_roundtrip_milliseconds *= config_roundtrip_multiplier;
+ config_roundtrip_milliseconds += roundtrip_milliseconds_increment;
+ } while (++params_index < kConfigFetchGroups);
sclittle 2015/05/12 19:32:25 Could this be done as a for loop instead for clari
jeremyim 2015/05/12 20:38:29 Done.
+ }
+
+ return scoped_ptr<DataReductionProxyExperimentsStats::ConfigRetrievalParams>(
+ new DataReductionProxyExperimentsStats::ConfigRetrievalParams(
+ variations, config_expiration, config_expiration_interval));
+}
+
+DataReductionProxyExperimentsStats::ConfigRetrievalParams::Variation::Variation(
+ int index,
+ const base::Time& simulated_config_retrieved)
+ : simulated_config_retrieved_(simulated_config_retrieved) {
+ lost_bytes_ocl_ = GetHistogramWithSuffix(
+ "DataReductionProxy.ConfigFetchLostBytesOCL_", index);
+ lost_bytes_rcl_ = GetHistogramWithSuffix(
+ "DataReductionProxy.ConfigFetchLostBytesCL_", index);
+ lost_bytes_diff_ = GetHistogramWithSuffix(
+ "DataReductionProxy.ConfigFetchLostBytesDiff_", index);
+}
+
+DataReductionProxyExperimentsStats::ConfigState
+DataReductionProxyExperimentsStats::ConfigRetrievalParams::Variation::GetState(
+ const base::Time& request_time,
+ const base::Time& config_expiration) const {
+ if (!simulated_config_retrieved_.is_null() &&
+ request_time < simulated_config_retrieved_) {
+ return DataReductionProxyExperimentsStats::RETRIEVING;
+ } else if (request_time < config_expiration) {
+ return DataReductionProxyExperimentsStats::VALID;
+ }
+
+ return DataReductionProxyExperimentsStats::EXPIRED;
+}
+
+void DataReductionProxyExperimentsStats::ConfigRetrievalParams::Variation::
+ RecordStats(int64 received_content_length,
+ int64 original_content_length) const {
+ lost_bytes_rcl_->Add(received_content_length);
+ lost_bytes_ocl_->Add(original_content_length);
+ lost_bytes_diff_->Add(original_content_length - received_content_length);
+}
+
+DataReductionProxyExperimentsStats::ConfigRetrievalParams::
+ ConfigRetrievalParams(const std::vector<Variation>& variations,
+ const base::Time& config_expiration,
+ const base::TimeDelta& config_expiration_interval)
+ : config_expiration_(config_expiration),
+ config_expiration_interval_(config_expiration_interval),
+ variations_(variations) {
+ config_refresh_interval_ =
+ config_expiration_interval_ -
+ base::TimeDelta::FromSeconds(experiments::kConfigFetchBufferSeconds);
+ if (config_refresh_interval_.InSeconds() <
+ kConfigFetchMinimumIntervalSeconds) {
+ config_refresh_interval_ =
+ base::TimeDelta::FromSeconds(kConfigFetchMinimumIntervalSeconds);
+ }
+}
+
+DataReductionProxyExperimentsStats::ConfigRetrievalParams::
+ ~ConfigRetrievalParams() {
+}
+
+void DataReductionProxyExperimentsStats::ConfigRetrievalParams::RecordStats(
+ const base::Time& request_time,
+ int64 received_content_length,
+ int64 original_content_length) const {
+ for (const auto& variation : variations_) {
+ switch (variation.GetState(request_time, config_expiration_)) {
+ case VALID:
+ break;
+ case RETRIEVING:
+ case EXPIRED:
+ variation.RecordStats(received_content_length, original_content_length);
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+}
+
+void DataReductionProxyExperimentsStats::ConfigRetrievalParams::
+ RefreshConfig() {
+ config_expiration_ = base::Time::Now() + config_expiration_interval_;
+}
+
+DataReductionProxyExperimentsStats::DataReductionProxyExperimentsStats(
+ Int64ValueSetter value_setter)
+ : value_setter_(value_setter) {
+ // Constructed on the UI thread, but should be checked on the IO thread.
+ thread_checker_.DetachFromThread();
+}
+
+DataReductionProxyExperimentsStats::~DataReductionProxyExperimentsStats() {
+}
+
+void DataReductionProxyExperimentsStats::InitializeOnUIThread(
+ scoped_ptr<ConfigRetrievalParams> config_retrieval_params) {
+ config_retrieval_params_ = config_retrieval_params.Pass();
+
+ // This method may be called from the UI thread, but should be checked on the
+ // IO thread.
+ thread_checker_.DetachFromThread();
+}
+
+void DataReductionProxyExperimentsStats::InitializeOnIOThread() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (config_retrieval_params_) {
+ config_refresh_time_.Start(
+ FROM_HERE, config_retrieval_params_->refresh_interval(), this,
+ &DataReductionProxyExperimentsStats::UpdateSimulatedConfig);
+ }
+}
+
+void DataReductionProxyExperimentsStats::RecordBytes(
+ const base::Time& request_time,
+ DataReductionProxyRequestType request_type,
+ int64 received_content_length,
+ int64 original_content_length) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (config_retrieval_params_) {
+ // Only measure requests which flowed through the Data Reduction Proxy.
+ if (request_type == VIA_DATA_REDUCTION_PROXY) {
+ config_retrieval_params_->RecordStats(
+ request_time, received_content_length, original_content_length);
+ }
+ }
+}
+
+void DataReductionProxyExperimentsStats::UpdateSimulatedConfig() {
+ if (config_retrieval_params_) {
+ value_setter_.Run(
+ prefs::kSimulatedConfigExpireTime,
+ config_retrieval_params_->config_expiration().ToInternalValue());
+ }
+}
+
+} // namespace data_reduction_proxy

Powered by Google App Engine
This is Rietveld 408576698