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

Unified Diff: net/nqe/network_quality_estimator.cc

Issue 2107243003: NQE: Record correlation metric in UMA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | net/nqe/network_quality_estimator_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/nqe/network_quality_estimator.cc
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc
index 256722a179b707ab1a3c37adc65e94bbe6b36e32..1d3642aa9ea64bd95e6abd9798b42c4a2ffa81c9 100644
--- a/net/nqe/network_quality_estimator.cc
+++ b/net/nqe/network_quality_estimator.cc
@@ -15,6 +15,8 @@
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_base.h"
+#include "base/metrics/sparse_histogram.h"
+#include "base/rand_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -25,9 +27,11 @@
#include "net/base/load_timing_info.h"
#include "net/base/network_interfaces.h"
#include "net/base/url_util.h"
+#include "net/http/http_status_code.h"
#include "net/nqe/socket_watcher_factory.h"
#include "net/nqe/throughput_analyzer.h"
#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_status.h"
#include "url/gurl.h"
#if defined(OS_ANDROID)
@@ -141,6 +145,22 @@ bool GetValueForVariationParam(
base::StringToInt(it->second, variations_value);
}
+// Returns the variation value for |parameter_name|. If the value is
+// unavailable, |default_value| is returned.
+double GetDoubleValueForVariationParamWithDefaultValue(
+ const std::map<std::string, std::string>& variation_params,
+ const std::string& parameter_name,
+ double default_value) {
+ const auto it = variation_params.find(parameter_name);
+ if (it == variation_params.end())
+ return default_value;
+
+ double variations_value = default_value;
+ if (!base::StringToDouble(it->second, &variations_value))
+ return default_value;
+ return variations_value;
+}
+
// Returns the algorithm that should be used for computing effective connection
// type based on field trial params. Returns an empty string if a valid
// algorithm paramter is not present in the field trial params.
@@ -188,6 +208,27 @@ std::string GetHistogramSuffixObservedRTT(const base::TimeDelta& observed_rtt) {
return kSuffixes[arraysize(kSuffixes) - 1];
}
+// The least significant kTrimBits of the metric will be discarded. Next, it
+// will be rounded down so it fits within kBitsPerMetric bits. This implies
+// that if the metric's value is more than 2^(kTrimBits + kBitsPerMetric),
+// then it will be rounded down.
Not at Google. Contact bengr 2016/06/30 17:49:44 This is confusing. Can you please rephrase it. How
tbansal1 2016/07/01 00:16:00 Done.
+const int32_t kTrimBits = 5;
+const int32_t kBitsPerMetric = 7;
Not at Google. Contact bengr 2016/06/30 17:49:44 Add: static_assert(31 > kBitsPerMetric * 4, "4 met
tbansal1 2016/07/01 00:16:00 Done.
+
+// Trims the |metric| by removing the last kTrimBits, and then rounding down
+// the |metric| such that the |metric| fits in kBitsPerMetric.
+int32_t TrimAndRoundDown(int32_t metric) {
Not at Google. Contact bengr 2016/06/30 17:49:44 Rename method to FitInKBitsPerMetricBits?
tbansal1 2016/07/01 00:16:00 Done.
+ // Remove the last kTrimBits. This will allow the metric to fit within
+ // kBitsPerMetric while losing only the least significant bits.
+ metric = metric >> kTrimBits;
+ if (metric >= (1 << kBitsPerMetric)) {
+ // Fit |metric| in kBitsPerMetric by rounding it down.
+ metric = (1 << kBitsPerMetric) - 1;
Not at Google. Contact bengr 2016/06/30 17:49:44 Possible Refactor: int32_t largest_value_using_kBi
tbansal1 2016/07/01 00:16:01 Done.
+ }
+ DCHECK_EQ(0, metric >> kBitsPerMetric);
+ return metric;
+}
+
} // namespace
namespace net {
@@ -230,6 +271,11 @@ NetworkQualityEstimator::NetworkQualityEstimator(
rtt_observations_(weight_multiplier_per_second_),
external_estimate_provider_(std::move(external_estimates_provider)),
effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
+ correlation_logging_probability_(
+ GetDoubleValueForVariationParamWithDefaultValue(
+ variation_params,
+ "correlation_logging_probability",
+ 0.0)),
weak_ptr_factory_(this) {
static_assert(kDefaultHalfLifeSeconds > 0,
"Default half life duration must be > 0");
@@ -249,6 +295,8 @@ NetworkQualityEstimator::NetworkQualityEstimator(
DCHECK_NE(EffectiveConnectionTypeAlgorithm::
EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST,
effective_connection_type_algorithm_);
+ DCHECK_LE(0.0, correlation_logging_probability_);
+ DCHECK_GE(1.0, correlation_logging_probability_);
ObtainOperatingParams(variation_params);
ObtainEffectiveConnectionTypeModelParams(variation_params);
@@ -490,6 +538,7 @@ void NetworkQualityEstimator::NotifyHeadersReceived(const URLRequest& request) {
load_timing_info.receive_headers_end.is_null()) {
return;
}
+ DCHECK(!request.response_info().was_cached);
// Duration between when the resource was requested and when the response
// headers were received.
@@ -584,6 +633,84 @@ void NetworkQualityEstimator::NotifyRequestCompleted(
return;
throughput_analyzer_->NotifyRequestCompleted(request);
+ RecordCorrelationMetric(request);
+}
+
+void NetworkQualityEstimator::RecordCorrelationMetric(
+ const URLRequest& request) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ // The histogram is recorded with probability
+ // |correlation_logging_probability_| to reduce overhead.
+ if (base::RandDouble() >= correlation_logging_probability_)
Not at Google. Contact bengr 2016/06/30 17:49:44 Shouldn't this be base::RandDouble() <= correlatio
tbansal1 2016/07/01 00:16:00 No. Say correlation_logging_probability_ is 1.0. T
Not at Google. Contact bengr 2016/07/01 18:26:26 Misread as condition to execute below. You are rig
+ return;
+
+ if (request.response_info().was_cached)
+ return;
+ LoadTimingInfo load_timing_info;
+ request.GetLoadTimingInfo(&load_timing_info);
+
+ // If the load timing info is unavailable, it probably means that the request
+ // did not go over the network.
Not at Google. Contact bengr 2016/06/30 17:49:44 Could this be replaced with request->response_info
tbansal1 2016/07/01 00:16:01 Done.
+ if (load_timing_info.send_start.is_null() ||
+ load_timing_info.receive_headers_end.is_null()) {
+ return;
+ }
+
+ // Record UMA only for successful requests that have completed.
+ if (!request.status().is_success() || request.status().is_io_pending())
+ return;
+ if (request.GetResponseCode() != HTTP_OK)
+ return;
+ if (load_timing_info.receive_headers_end < last_main_frame_request_)
+ return;
Not at Google. Contact bengr 2016/06/30 17:49:44 Nit: Add new line.
tbansal1 2016/07/01 00:16:00 Done.
+ const base::TimeTicks now = tick_clock_->NowTicks();
+ // Record UMA only for requests that started recently.
+ if (now - last_main_frame_request_ > base::TimeDelta::FromSeconds(15))
Not at Google. Contact bengr 2016/06/30 17:49:44 Why ignore older requests?
tbansal1 2016/07/01 00:16:00 It is possible that network quality was recorded a
Not at Google. Contact bengr 2016/07/01 18:26:26 Acknowledged.
+ return;
+
+ DCHECK_GE(now, load_timing_info.send_start);
Not at Google. Contact bengr 2016/06/30 17:49:44 Not sure this is necessary.
tbansal1 2016/07/01 00:16:01 It checks that we are not adding negative values t
Not at Google. Contact bengr 2016/07/01 18:26:26 Acknowledged.
+
+ // Histogram samples are 32-bit in size with first bit reserved for sign.
+ // Four metrics will be recorded per sample.
+ DCHECK_GE(31, kBitsPerMetric * 4);
Not at Google. Contact bengr 2016/06/30 17:49:44 Prefer replacing with static assert above where kB
tbansal1 2016/07/01 00:16:01 Done.
+
+ const int32_t transport_rtt_milliseconds =
Not at Google. Contact bengr 2016/06/30 17:49:44 Does it help to extract estimated_quality_at_last_
tbansal1 2016/07/01 00:16:00 I am not sure. I wanted to declare it as a const v
+ estimated_quality_at_last_main_frame_.transport_rtt() !=
+ nqe::internal::InvalidRTT()
+ ? TrimAndRoundDown(
+ estimated_quality_at_last_main_frame_.transport_rtt()
+ .InMilliseconds())
+ : 0;
+
+ const int32_t http_rtt_milliseconds =
+ estimated_quality_at_last_main_frame_.http_rtt() !=
+ nqe::internal::InvalidRTT()
+ ? TrimAndRoundDown(estimated_quality_at_last_main_frame_.http_rtt()
+ .InMilliseconds())
+ : 0;
+
+ const int32_t downstream_throughput_kbps =
+ estimated_quality_at_last_main_frame_.downstream_throughput_kbps() !=
+ nqe::internal::kInvalidThroughput
+ ? TrimAndRoundDown(estimated_quality_at_last_main_frame_
+ .downstream_throughput_kbps())
+ : 0;
+
+ const int32_t resource_load_time_milliseconds =
+ TrimAndRoundDown((now - load_timing_info.send_start).InMilliseconds());
+
+ // First 32 - (4* kBitsPerMetric) of the sample are unset. Next
+ // kBitsPerMetric of the sample contain |transport_rtt_milliseconds|.
+ // Next kBitsPerMetric contain |http_rtt_milliseconds|. Next kBitsPerMetric
+ // contain |downstream_throughput_kbps|. And, the last kBitsPerMetric
+ // contain |resource_load_time_milliseconds|.
+ int32_t sample = transport_rtt_milliseconds;
Not at Google. Contact bengr 2016/06/30 17:49:44 Suggest adding DCHECK_EQ(0, transport_rtt_millisec
tbansal1 2016/07/01 00:16:00 Done.
+ sample = (sample << kBitsPerMetric) + http_rtt_milliseconds;
Not at Google. Contact bengr 2016/06/30 17:49:44 Minor: | seems prefereable to +.
tbansal1 2016/07/01 00:16:00 Done.
+ sample = (sample << kBitsPerMetric) + downstream_throughput_kbps;
+ sample = (sample << kBitsPerMetric) + resource_load_time_milliseconds;
+
+ UMA_HISTOGRAM_SPARSE_SLOWLY("NQE.Correlation.ResourceLoadTime", sample);
}
void NetworkQualityEstimator::NotifyURLRequestDestroyed(
« no previous file with comments | « net/nqe/network_quality_estimator.h ('k') | net/nqe/network_quality_estimator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698