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

Side by Side Diff: net/nqe/network_quality_estimator.cc

Issue 2032443003: NQE: Allow algorithm to be set using variation params (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor fix in DCHECK evaluation 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "net/nqe/network_quality_estimator.h" 5 #include "net/nqe/network_quality_estimator.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <utility> 10 #include <utility>
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 const char prefix[] = "NQE."; 127 const char prefix[] = "NQE.";
128 return base::Histogram::FactoryGet( 128 return base::Histogram::FactoryGet(
129 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit, 129 prefix + statistic_name + GetNameForConnectionType(type), kLowerLimit,
130 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag); 130 max_limit, kBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag);
131 } 131 }
132 132
133 bool GetValueForVariationParam( 133 bool GetValueForVariationParam(
134 const std::map<std::string, std::string>& variation_params, 134 const std::map<std::string, std::string>& variation_params,
135 const std::string& parameter_name, 135 const std::string& parameter_name,
136 int32_t* variations_value) { 136 int32_t* variations_value) {
137 auto it = variation_params.find(parameter_name); 137 const auto it = variation_params.find(parameter_name);
138 return it != variation_params.end() && 138 return it != variation_params.end() &&
139 base::StringToInt(it->second, variations_value); 139 base::StringToInt(it->second, variations_value);
140 } 140 }
141 141
142 // Returns the algorithm that should be used for computing effective connection
143 // type based on field trial params. Returns an empty string if a valid
144 // algorithm paramter is not present in the field trial params.
145 std::string GetEffectiveConnectionTypeAlgorithm(
146 const std::map<std::string, std::string>& variation_params) {
147 const auto it = variation_params.find("effective_connection_type_algorithm");
148 if (it == variation_params.end())
149 return std::string();
150 return it->second;
151 }
152
142 net::NetworkQualityObservationSource ProtocolSourceToObservationSource( 153 net::NetworkQualityObservationSource ProtocolSourceToObservationSource(
143 net::SocketPerformanceWatcherFactory::Protocol protocol) { 154 net::SocketPerformanceWatcherFactory::Protocol protocol) {
144 switch (protocol) { 155 switch (protocol) {
145 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP: 156 case net::SocketPerformanceWatcherFactory::PROTOCOL_TCP:
146 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; 157 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP;
147 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC: 158 case net::SocketPerformanceWatcherFactory::PROTOCOL_QUIC:
148 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC; 159 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC;
149 } 160 }
150 NOTREACHED(); 161 NOTREACHED();
151 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP; 162 return net::NETWORK_QUALITY_OBSERVATION_SOURCE_TCP;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 : NetworkQualityEstimator(std::move(external_estimates_provider), 196 : NetworkQualityEstimator(std::move(external_estimates_provider),
186 variation_params, 197 variation_params,
187 false, 198 false,
188 false) {} 199 false) {}
189 200
190 NetworkQualityEstimator::NetworkQualityEstimator( 201 NetworkQualityEstimator::NetworkQualityEstimator(
191 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider, 202 std::unique_ptr<ExternalEstimateProvider> external_estimates_provider,
192 const std::map<std::string, std::string>& variation_params, 203 const std::map<std::string, std::string>& variation_params,
193 bool use_local_host_requests_for_tests, 204 bool use_local_host_requests_for_tests,
194 bool use_smaller_responses_for_tests) 205 bool use_smaller_responses_for_tests)
195 : use_localhost_requests_(use_local_host_requests_for_tests), 206 : algorithm_name_to_enum_({{"HttpRTTAndDownstreamThroughput",
207 EffectiveConnectionTypeAlgorithm::
208 HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT}}),
209 use_localhost_requests_(use_local_host_requests_for_tests),
196 use_small_responses_(use_smaller_responses_for_tests), 210 use_small_responses_(use_smaller_responses_for_tests),
197 weight_multiplier_per_second_( 211 weight_multiplier_per_second_(
198 GetWeightMultiplierPerSecond(variation_params)), 212 GetWeightMultiplierPerSecond(variation_params)),
213 effective_connection_type_algorithm_(
214 algorithm_name_to_enum_.find(GetEffectiveConnectionTypeAlgorithm(
215 variation_params)) == algorithm_name_to_enum_.end()
216 ? kDefaultEffectiveConnectionTypeAlgorithm
217 : algorithm_name_to_enum_
218 .find(GetEffectiveConnectionTypeAlgorithm(variation_params))
219 ->second),
199 tick_clock_(new base::DefaultTickClock()), 220 tick_clock_(new base::DefaultTickClock()),
200 effective_connection_type_recomputation_interval_( 221 effective_connection_type_recomputation_interval_(
201 base::TimeDelta::FromSeconds(15)), 222 base::TimeDelta::FromSeconds(15)),
202 last_connection_change_(tick_clock_->NowTicks()), 223 last_connection_change_(tick_clock_->NowTicks()),
203 current_network_id_( 224 current_network_id_(
204 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, 225 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN,
205 std::string())), 226 std::string())),
206 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), 227 downstream_throughput_kbps_observations_(weight_multiplier_per_second_),
207 rtt_observations_(weight_multiplier_per_second_), 228 rtt_observations_(weight_multiplier_per_second_),
208 external_estimate_provider_(std::move(external_estimates_provider)), 229 external_estimate_provider_(std::move(external_estimates_provider)),
209 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), 230 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
210 weak_ptr_factory_(this) { 231 weak_ptr_factory_(this) {
211 static_assert(kDefaultHalfLifeSeconds > 0, 232 static_assert(kDefaultHalfLifeSeconds > 0,
212 "Default half life duration must be > 0"); 233 "Default half life duration must be > 0");
213 static_assert(kMaximumNetworkQualityCacheSize > 0, 234 static_assert(kMaximumNetworkQualityCacheSize > 0,
214 "Size of the network quality cache must be > 0"); 235 "Size of the network quality cache must be > 0");
215 // This limit should not be increased unless the logic for removing the 236 // This limit should not be increased unless the logic for removing the
216 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue. 237 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue.
217 static_assert(kMaximumNetworkQualityCacheSize <= 10, 238 static_assert(kMaximumNetworkQualityCacheSize <= 10,
218 "Size of the network quality cache must <= 10"); 239 "Size of the network quality cache must <= 10");
240 // None of the algorithms can have an empty name.
241 DCHECK(algorithm_name_to_enum_.end() ==
242 algorithm_name_to_enum_.find(std::string()));
243
244 DCHECK_EQ(algorithm_name_to_enum_.size(),
245 static_cast<size_t>(EffectiveConnectionTypeAlgorithm::
246 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST));
247 DCHECK_NE(EffectiveConnectionTypeAlgorithm::
248 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST,
249 effective_connection_type_algorithm_);
219 250
220 ObtainOperatingParams(variation_params); 251 ObtainOperatingParams(variation_params);
221 ObtainEffectiveConnectionTypeModelParams(variation_params); 252 ObtainEffectiveConnectionTypeModelParams(variation_params);
222 NetworkChangeNotifier::AddConnectionTypeObserver(this); 253 NetworkChangeNotifier::AddConnectionTypeObserver(this);
223 if (external_estimate_provider_) { 254 if (external_estimate_provider_) {
224 RecordExternalEstimateProviderMetrics( 255 RecordExternalEstimateProviderMetrics(
225 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); 256 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE);
226 external_estimate_provider_->SetUpdatedEstimateDelegate(this); 257 external_estimate_provider_->SetUpdatedEstimateDelegate(this);
227 } else { 258 } else {
228 RecordExternalEstimateProviderMetrics( 259 RecordExternalEstimateProviderMetrics(
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 NetworkQualityEstimator::GetEffectiveConnectionType() const { 780 NetworkQualityEstimator::GetEffectiveConnectionType() const {
750 DCHECK(thread_checker_.CalledOnValidThread()); 781 DCHECK(thread_checker_.CalledOnValidThread());
751 return GetRecentEffectiveConnectionType(base::TimeTicks()); 782 return GetRecentEffectiveConnectionType(base::TimeTicks());
752 } 783 }
753 784
754 NetworkQualityEstimator::EffectiveConnectionType 785 NetworkQualityEstimator::EffectiveConnectionType
755 NetworkQualityEstimator::GetRecentEffectiveConnectionType( 786 NetworkQualityEstimator::GetRecentEffectiveConnectionType(
756 const base::TimeTicks& start_time) const { 787 const base::TimeTicks& start_time) const {
757 DCHECK(thread_checker_.CalledOnValidThread()); 788 DCHECK(thread_checker_.CalledOnValidThread());
758 789
790 if (effective_connection_type_algorithm_ ==
791 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) {
792 return GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput(
793 start_time);
794 }
795 // Add additional algorithms here.
796 NOTREACHED();
797 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
798 }
799
800 NetworkQualityEstimator::EffectiveConnectionType NetworkQualityEstimator::
801 GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput(
802 const base::TimeTicks& start_time) const {
803 DCHECK(thread_checker_.CalledOnValidThread());
804
759 // If the device is currently offline, then return 805 // If the device is currently offline, then return
760 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. 806 // EFFECTIVE_CONNECTION_TYPE_OFFLINE.
761 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE) 807 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE)
762 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; 808 return EFFECTIVE_CONNECTION_TYPE_OFFLINE;
763 809
764 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); 810 base::TimeDelta http_rtt = nqe::internal::InvalidRTT();
765 if (!GetRecentHttpRTTMedian(start_time, &http_rtt)) 811 if (!GetRecentHttpRTTMedian(start_time, &http_rtt))
766 http_rtt = nqe::internal::InvalidRTT(); 812 http_rtt = nqe::internal::InvalidRTT();
767 813
768 int32_t kbps = nqe::internal::kInvalidThroughput; 814 int32_t kbps = nqe::internal::kInvalidThroughput;
769 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps)) 815 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps))
770 kbps = nqe::internal::kInvalidThroughput; 816 kbps = nqe::internal::kInvalidThroughput;
771 817
772 if (http_rtt == nqe::internal::InvalidRTT() && 818 if (http_rtt == nqe::internal::InvalidRTT() ||
773 kbps == nqe::internal::kInvalidThroughput) { 819 kbps == nqe::internal::kInvalidThroughput) {
774 // Quality of the current network is unknown. 820 // Quality of the current network is unknown.
775 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; 821 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
776 } 822 }
777 823
778 // Search from the slowest connection type to the fastest to find the 824 // Search from the slowest connection type to the fastest to find the
779 // EffectiveConnectionType that best matches the current connection's 825 // EffectiveConnectionType that best matches the current connection's
780 // performance. The match is done by comparing RTT and throughput. 826 // performance. The match is done by comparing RTT and throughput.
781 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { 827 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) {
782 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i); 828 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i);
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 NotifyObserversOfEffectiveConnectionTypeChanged() { 1237 NotifyObserversOfEffectiveConnectionTypeChanged() {
1192 DCHECK(thread_checker_.CalledOnValidThread()); 1238 DCHECK(thread_checker_.CalledOnValidThread());
1193 1239
1194 // TODO(tbansal): Add hysteresis in the notification. 1240 // TODO(tbansal): Add hysteresis in the notification.
1195 FOR_EACH_OBSERVER( 1241 FOR_EACH_OBSERVER(
1196 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, 1242 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_,
1197 OnEffectiveConnectionTypeChanged(effective_connection_type_)); 1243 OnEffectiveConnectionTypeChanged(effective_connection_type_));
1198 } 1244 }
1199 1245
1200 } // namespace net 1246 } // namespace net
OLDNEW
« 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