1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_NQE_NETWORK_QUALITY_ESTIMATOR_PARAMS_H_
#define NET_NQE_NETWORK_QUALITY_ESTIMATOR_PARAMS_H_
#include <array>
#include <map>
#include <optional>
#include <string>
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
#include "net/nqe/effective_connection_type.h"
#include "net/nqe/network_quality.h"
namespace net {
// Forces NQE to return a specific effective connection type. Set using the
// |params| provided to the NetworkQualityEstimatorParams constructor.
NET_EXPORT extern const char kForceEffectiveConnectionType[];
NET_EXPORT extern const char kEffectiveConnectionTypeSlow2GOnCellular[];
// HTTP RTT thresholds for different effective connection types.
inline constexpr std::array<base::TimeDelta, EFFECTIVE_CONNECTION_TYPE_LAST>
kHttpRttEffectiveConnectionTypeThresholds = {
base::Milliseconds(0), base::Milliseconds(0),
base::Milliseconds(2010), base::Milliseconds(1420),
base::Milliseconds(272), base::Milliseconds(0)};
// NetworkQualityEstimatorParams computes the configuration parameters for
// the network quality estimator.
class NET_EXPORT NetworkQualityEstimatorParams {
public:
// |params| is the map containing all field trial parameters related to
// NetworkQualityEstimator field trial.
explicit NetworkQualityEstimatorParams(
const std::map<std::string, std::string>& params);
NetworkQualityEstimatorParams(const NetworkQualityEstimatorParams&) = delete;
NetworkQualityEstimatorParams& operator=(
const NetworkQualityEstimatorParams&) = delete;
~NetworkQualityEstimatorParams();
// Returns the default observation for connection |type|. The default
// observations are different for different connection types (e.g., 2G, 3G,
// 4G, WiFi). The default observations may be used to determine the network
// quality in absence of any other information.
const nqe::internal::NetworkQuality& DefaultObservation(
NetworkChangeNotifier::ConnectionType type) const;
// Returns the typical network quality for connection |type|.
const nqe::internal::NetworkQuality& TypicalNetworkQuality(
EffectiveConnectionType type) const;
// Returns the threshold for effective connection type |type|.
const nqe::internal::NetworkQuality& ConnectionThreshold(
EffectiveConnectionType type) const;
// Returns the minimum number of requests in-flight to consider the network
// fully utilized. A throughput observation is taken only when the network is
// considered as fully utilized.
size_t throughput_min_requests_in_flight() const;
// Tiny transfer sizes may give inaccurate throughput results.
// Minimum size of the transfer over which the throughput is computed.
int64_t GetThroughputMinTransferSizeBits() const;
// Returns the weight multiplier per second, which represents the factor by
// which the weight of an observation reduces every second.
double weight_multiplier_per_second() const {
return weight_multiplier_per_second_;
}
// Returns an unset value if the effective connection type has not been forced
// via the |params| provided to this class. Otherwise, returns a value set to
// the effective connection type that has been forced. Forced ECT can be
// forced based on |connection_type| (e.g. Slow-2G on cellular, and default on
// other connection type).
std::optional<EffectiveConnectionType> GetForcedEffectiveConnectionType(
NetworkChangeNotifier::ConnectionType connection_type);
void SetForcedEffectiveConnectionType(
EffectiveConnectionType forced_effective_connection_type) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
forced_effective_connection_type_ = forced_effective_connection_type;
}
// Returns true if reading from the persistent cache is enabled.
bool persistent_cache_reading_enabled() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return persistent_cache_reading_enabled_;
}
void set_persistent_cache_reading_enabled(
bool persistent_cache_reading_enabled) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
persistent_cache_reading_enabled_ = persistent_cache_reading_enabled;
}
// Returns the the minimum interval betweeen consecutive notifications to a
// single socket watcher.
base::TimeDelta min_socket_watcher_notification_interval() const {
return min_socket_watcher_notification_interval_;
}
// Number of bytes received during a throughput observation window of duration
// 1 HTTP RTT should be at least the value returned by this method times
// the typical size of a congestion window. If not, the throughput observation
// window is heuristically determined as hanging.
double throughput_hanging_requests_cwnd_size_multiplier() const {
return throughput_hanging_requests_cwnd_size_multiplier_;
}
// Returns the multiplier by which the transport RTT should be multipled when
// computing the HTTP RTT. The multiplied value of the transport RTT serves
// as a lower bound to the HTTP RTT estimate. e.g., if the multiplied
// transport RTT is 100 msec., then HTTP RTT estimate can't be lower than
// 100 msec. Returns a negative value if the param is not set.
double lower_bound_http_rtt_transport_rtt_multiplier() const {
return lower_bound_http_rtt_transport_rtt_multiplier_;
}
// Returns the multiplier by which the end to end RTT estimate should be
// multiplied when computing the HTTP RTT. The multiplied value of the
// end to end RTT serves as an upper bound to the HTTP RTT estimate. e.g., if
// the multiplied end to end RTT is 100 msec., then HTTP RTT estimate can't be
// more than |upper_bound_http_rtt_endtoend_rtt_multiplier| times 100 msec.
// Returns a negative value if the param is not set.
double upper_bound_http_rtt_endtoend_rtt_multiplier() const {
return upper_bound_http_rtt_endtoend_rtt_multiplier_;
}
// For the purpose of estimating the HTTP RTT, a request is marked as hanging
// only if its RTT is at least this times the transport RTT estimate.
int hanging_request_http_rtt_upper_bound_transport_rtt_multiplier() const {
return hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_;
}
// For the purpose of estimating the HTTP RTT, a request is marked as hanging
// only if its RTT is at least this times the HTTP RTT estimate.
int hanging_request_http_rtt_upper_bound_http_rtt_multiplier() const {
return hanging_request_http_rtt_upper_bound_http_rtt_multiplier_;
}
// For the purpose of estimating the HTTP RTT, a request is marked as hanging
// only if its RTT is at least as much the value returned by this method.
base::TimeDelta hanging_request_upper_bound_min_http_rtt() const {
return hanging_request_upper_bound_min_http_rtt_;
}
// Returns the number of transport RTT observations that should be available
// before the transport RTT estimate can be used to clamp the HTTP RTT
// estimate. Set to 5 by default which ensures that when the transport RTT
// is available only from the connection type, it is not used for computing
// the HTTP RTT estimate.
size_t http_rtt_transport_rtt_min_count() const {
return http_rtt_transport_rtt_min_count_;
}
// Returns the minimum interval between successive computations of the
// increase in transport RTT.
base::TimeDelta increase_in_transport_rtt_logging_interval() const {
return increase_in_transport_rtt_logging_interval_;
}
// The maximum age of RTT observations for them to be considered recent for
// the computation of the increase in RTT.
base::TimeDelta recent_time_threshold() const {
return recent_time_threshold_;
}
// The maximum age of observations for them to be considered useful for
// calculating the minimum transport RTT from the historical data.
base::TimeDelta historical_time_threshold() const {
return historical_time_threshold_;
}
// Determines if the responses smaller than |kMinTransferSizeInBytes|
// or shorter than |kMinTransferSizeInBytes| can be used in estimating the
// network quality. Set to true only for tests.
bool use_small_responses() const;
// Returns the typical HTTP RTT that maps to the given
// |effective_connection_type|. May return invalid value if
// |effective_connection_type| is less than Slow2G or faster than 4G,
static base::TimeDelta GetDefaultTypicalHttpRtt(
EffectiveConnectionType effective_connection_type);
// Returns the typical downslink throughput (in kbps) that maps to the given
// |effective_connection_type|. May return invalid value if
// |effective_connection_type| is less than Slow2G or faster than 4G,
static int32_t GetDefaultTypicalDownlinkKbps(
EffectiveConnectionType effective_connection_type);
// |use_small_responses| should only be true when testing.
// Allows the responses smaller than |kMinTransferSizeInBits| to be used for
// network quality estimation.
void SetUseSmallResponsesForTesting(bool use_small_responses);
// If an in-flight request does not receive any data for a duration longer
// than the value of this multiplier times the current HTTP RTT estimate, then
// the request should be considered as hanging. If this multiplier has a
// negative or a zero value, then none of the request should be considered as
// hanging.
int hanging_request_duration_http_rtt_multiplier() const {
return hanging_request_duration_http_rtt_multiplier_;
}
// An in-flight request may be marked as hanging only if it does not receive
// any data for at least this duration.
base::TimeDelta hanging_request_min_duration() const {
return hanging_request_min_duration_;
}
// Returns true if default values provided by the platform should be used for
// estimation. Set to false only for testing.
bool add_default_platform_observations() const {
return add_default_platform_observations_;
}
// Number of observations received after which the effective connection type
// should be recomputed.
size_t count_new_observations_received_compute_ect() const {
return count_new_observations_received_compute_ect_;
}
// Maximum number of observations that can be held in a single
// ObservationBuffer.
size_t observation_buffer_size() const { return observation_buffer_size_; }
// Minimun interval between consecutive notifications from socket
// watchers who live on the same thread as the network quality estimator.
base::TimeDelta socket_watchers_min_notification_interval() const {
return socket_watchers_min_notification_interval_;
}
// Returns true if end-to-end RTT estimates can be used for computing network
// quality estimate.
bool use_end_to_end_rtt() const { return use_end_to_end_rtt_; }
// Returns a multiplier which is used to clamp Kbps on slow connections. For
// a given ECT, the upper bound on Kbps is computed based on this returned
// multiplier and the typical Kbps for the given ECT. If
// upper_bound_typical_kbps_multiplier() is -1, then clamping should be
// disabled.
double upper_bound_typical_kbps_multiplier() const {
return upper_bound_typical_kbps_multiplier_;
}
// Returns true if RTTs should be adjusted based on RTT counts.
// If there are not enough transport RTT samples, end-to-end RTT samples and
// the cached estimates are unavailble/too stale, then the computed value of
// HTTP RTT can't be trusted due to hanging GETs. In that case, NQE returns
// the typical HTTP RTT for a fast connection if
// adjust_rtt_based_on_rtt_counts() returns true.
bool adjust_rtt_based_on_rtt_counts() const {
return adjust_rtt_based_on_rtt_counts_;
}
// Sets the forced effective connection type as |type|.
void SetForcedEffectiveConnectionTypeForTesting(EffectiveConnectionType type);
private:
// Map containing all field trial parameters related to
// NetworkQualityEstimator field trial.
const std::map<std::string, std::string> params_;
const size_t throughput_min_requests_in_flight_;
const int throughput_min_transfer_size_kilobytes_;
const double throughput_hanging_requests_cwnd_size_multiplier_;
const double weight_multiplier_per_second_;
std::optional<EffectiveConnectionType> forced_effective_connection_type_;
const bool forced_effective_connection_type_on_cellular_only_;
bool persistent_cache_reading_enabled_;
const base::TimeDelta min_socket_watcher_notification_interval_;
const double lower_bound_http_rtt_transport_rtt_multiplier_ = 1.0;
const double upper_bound_http_rtt_endtoend_rtt_multiplier_;
const int hanging_request_http_rtt_upper_bound_transport_rtt_multiplier_;
const int hanging_request_http_rtt_upper_bound_http_rtt_multiplier_;
const base::TimeDelta hanging_request_upper_bound_min_http_rtt_ =
base::Milliseconds(500);
const size_t http_rtt_transport_rtt_min_count_;
const base::TimeDelta increase_in_transport_rtt_logging_interval_;
const base::TimeDelta recent_time_threshold_;
const base::TimeDelta historical_time_threshold_;
const int hanging_request_duration_http_rtt_multiplier_;
const base::TimeDelta hanging_request_min_duration_ =
base::Milliseconds(3000);
const bool add_default_platform_observations_;
const size_t count_new_observations_received_compute_ect_;
const size_t observation_buffer_size_;
const base::TimeDelta socket_watchers_min_notification_interval_;
const bool use_end_to_end_rtt_ = true;
const double upper_bound_typical_kbps_multiplier_;
const bool adjust_rtt_based_on_rtt_counts_;
bool use_small_responses_ = false;
// Default network quality observations obtained from |params_|.
std::array<nqe::internal::NetworkQuality,
NetworkChangeNotifier::CONNECTION_LAST + 1>
default_observations_;
// Typical network quality for different effective connection types obtained
// from |params_|.
std::array<nqe::internal::NetworkQuality,
EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_LAST>
typical_network_quality_;
// Thresholds for different effective connection types obtained from
// |params_|. These thresholds encode how different connection types behave
// in general.
std::array<nqe::internal::NetworkQuality,
EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_LAST>
connection_thresholds_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace net
#endif // NET_NQE_NETWORK_QUALITY_ESTIMATOR_PARAMS_H_
|