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

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: Rebased 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
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("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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 : use_localhost_requests_(use_local_host_requests_for_tests),
196 use_small_responses_(use_smaller_responses_for_tests), 207 use_small_responses_(use_smaller_responses_for_tests),
197 weight_multiplier_per_second_( 208 weight_multiplier_per_second_(
198 GetWeightMultiplierPerSecond(variation_params)), 209 GetWeightMultiplierPerSecond(variation_params)),
210 algorithm_(
211 stringToAlgorithm_.find(GetEffectiveConnectionTypeAlgorithm(
212 variation_params)) == stringToAlgorithm_.end()
213 ? kDefaultEffectiveConnectionTypeAlgorithm
214 : stringToAlgorithm_
215 .find(GetEffectiveConnectionTypeAlgorithm(variation_params))
216 ->second),
199 tick_clock_(new base::DefaultTickClock()), 217 tick_clock_(new base::DefaultTickClock()),
200 effective_connection_type_recomputation_interval_( 218 effective_connection_type_recomputation_interval_(
201 base::TimeDelta::FromSeconds(15)), 219 base::TimeDelta::FromSeconds(15)),
202 last_connection_change_(tick_clock_->NowTicks()), 220 last_connection_change_(tick_clock_->NowTicks()),
203 current_network_id_( 221 current_network_id_(
204 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, 222 NetworkID(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN,
205 std::string())), 223 std::string())),
206 downstream_throughput_kbps_observations_(weight_multiplier_per_second_), 224 downstream_throughput_kbps_observations_(weight_multiplier_per_second_),
207 rtt_observations_(weight_multiplier_per_second_), 225 rtt_observations_(weight_multiplier_per_second_),
208 external_estimate_provider_(std::move(external_estimates_provider)), 226 external_estimate_provider_(std::move(external_estimates_provider)),
209 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), 227 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
210 weak_ptr_factory_(this) { 228 weak_ptr_factory_(this) {
211 static_assert(kDefaultHalfLifeSeconds > 0, 229 static_assert(kDefaultHalfLifeSeconds > 0,
212 "Default half life duration must be > 0"); 230 "Default half life duration must be > 0");
213 static_assert(kMaximumNetworkQualityCacheSize > 0, 231 static_assert(kMaximumNetworkQualityCacheSize > 0,
214 "Size of the network quality cache must be > 0"); 232 "Size of the network quality cache must be > 0");
215 // This limit should not be increased unless the logic for removing the 233 // 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. 234 // oldest cache entry is rewritten to use a doubly-linked-list LRU queue.
217 static_assert(kMaximumNetworkQualityCacheSize <= 10, 235 static_assert(kMaximumNetworkQualityCacheSize <= 10,
218 "Size of the network quality cache must <= 10"); 236 "Size of the network quality cache must <= 10");
237 // None of the algorithms can have an empty name.
238 DCHECK(stringToAlgorithm_.end() == stringToAlgorithm_.find(std::string()));
bengr 2016/06/08 23:33:11 Construction of the map should go write before thi
tbansal1 2016/06/08 23:48:29 Not doing this as discussed offline.
239
240 DCHECK_EQ(stringToAlgorithm_.size(),
241 static_cast<size_t>(EffectiveConnectionTypeAlgorithm::
242 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST));
243 DCHECK_NE(EffectiveConnectionTypeAlgorithm::
244 EFFECTIVE_CONNECTION_TYPE_ALGORITHM_LAST,
245 algorithm_);
219 246
220 ObtainOperatingParams(variation_params); 247 ObtainOperatingParams(variation_params);
221 ObtainEffectiveConnectionTypeModelParams(variation_params); 248 ObtainEffectiveConnectionTypeModelParams(variation_params);
222 NetworkChangeNotifier::AddConnectionTypeObserver(this); 249 NetworkChangeNotifier::AddConnectionTypeObserver(this);
223 if (external_estimate_provider_) { 250 if (external_estimate_provider_) {
224 RecordExternalEstimateProviderMetrics( 251 RecordExternalEstimateProviderMetrics(
225 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE); 252 EXTERNAL_ESTIMATE_PROVIDER_STATUS_AVAILABLE);
226 external_estimate_provider_->SetUpdatedEstimateDelegate(this); 253 external_estimate_provider_->SetUpdatedEstimateDelegate(this);
227 } else { 254 } else {
228 RecordExternalEstimateProviderMetrics( 255 RecordExternalEstimateProviderMetrics(
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 NetworkQualityEstimator::GetEffectiveConnectionType() const { 776 NetworkQualityEstimator::GetEffectiveConnectionType() const {
750 DCHECK(thread_checker_.CalledOnValidThread()); 777 DCHECK(thread_checker_.CalledOnValidThread());
751 return GetRecentEffectiveConnectionType(base::TimeTicks()); 778 return GetRecentEffectiveConnectionType(base::TimeTicks());
752 } 779 }
753 780
754 NetworkQualityEstimator::EffectiveConnectionType 781 NetworkQualityEstimator::EffectiveConnectionType
755 NetworkQualityEstimator::GetRecentEffectiveConnectionType( 782 NetworkQualityEstimator::GetRecentEffectiveConnectionType(
756 const base::TimeTicks& start_time) const { 783 const base::TimeTicks& start_time) const {
757 DCHECK(thread_checker_.CalledOnValidThread()); 784 DCHECK(thread_checker_.CalledOnValidThread());
758 785
786 if (algorithm_ ==
787 EffectiveConnectionTypeAlgorithm::HTTP_RTT_AND_DOWNSTREAM_THROUGHOUT) {
788 return GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput(
789 start_time);
790 }
791 // Add additional algorithms here.
792 NOTREACHED();
793 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
794 }
795
796 NetworkQualityEstimator::EffectiveConnectionType NetworkQualityEstimator::
797 GetRecentEffectiveConnectionTypeHttpRTTAndDownstreamThroughput(
798 const base::TimeTicks& start_time) const {
799 DCHECK(thread_checker_.CalledOnValidThread());
800
759 // If the device is currently offline, then return 801 // If the device is currently offline, then return
760 // EFFECTIVE_CONNECTION_TYPE_OFFLINE. 802 // EFFECTIVE_CONNECTION_TYPE_OFFLINE.
761 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE) 803 if (GetCurrentNetworkID().type == NetworkChangeNotifier::CONNECTION_NONE)
762 return EFFECTIVE_CONNECTION_TYPE_OFFLINE; 804 return EFFECTIVE_CONNECTION_TYPE_OFFLINE;
763 805
764 base::TimeDelta http_rtt = nqe::internal::InvalidRTT(); 806 base::TimeDelta http_rtt = nqe::internal::InvalidRTT();
765 if (!GetRecentHttpRTTMedian(start_time, &http_rtt)) 807 if (!GetRecentHttpRTTMedian(start_time, &http_rtt))
766 http_rtt = nqe::internal::InvalidRTT(); 808 http_rtt = nqe::internal::InvalidRTT();
767 809
768 int32_t kbps = nqe::internal::kInvalidThroughput; 810 int32_t kbps = nqe::internal::kInvalidThroughput;
769 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps)) 811 if (!GetRecentMedianDownlinkThroughputKbps(start_time, &kbps))
770 kbps = nqe::internal::kInvalidThroughput; 812 kbps = nqe::internal::kInvalidThroughput;
771 813
772 if (http_rtt == nqe::internal::InvalidRTT() && 814 if (http_rtt == nqe::internal::InvalidRTT() ||
773 kbps == nqe::internal::kInvalidThroughput) { 815 kbps == nqe::internal::kInvalidThroughput) {
774 // Quality of the current network is unknown. 816 // Quality of the current network is unknown.
775 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; 817 return EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
776 } 818 }
777 819
778 // Search from the slowest connection type to the fastest to find the 820 // Search from the slowest connection type to the fastest to find the
779 // EffectiveConnectionType that best matches the current connection's 821 // EffectiveConnectionType that best matches the current connection's
780 // performance. The match is done by comparing RTT and throughput. 822 // performance. The match is done by comparing RTT and throughput.
781 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { 823 for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) {
782 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i); 824 EffectiveConnectionType type = static_cast<EffectiveConnectionType>(i);
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 NotifyObserversOfEffectiveConnectionTypeChanged() { 1233 NotifyObserversOfEffectiveConnectionTypeChanged() {
1192 DCHECK(thread_checker_.CalledOnValidThread()); 1234 DCHECK(thread_checker_.CalledOnValidThread());
1193 1235
1194 // TODO(tbansal): Add hysteresis in the notification. 1236 // TODO(tbansal): Add hysteresis in the notification.
1195 FOR_EACH_OBSERVER( 1237 FOR_EACH_OBSERVER(
1196 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_, 1238 EffectiveConnectionTypeObserver, effective_connection_type_observer_list_,
1197 OnEffectiveConnectionTypeChanged(effective_connection_type_)); 1239 OnEffectiveConnectionTypeChanged(effective_connection_type_));
1198 } 1240 }
1199 1241
1200 } // namespace net 1242 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698