Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/throughput_analyzer.h" | 5 #include "net/nqe/throughput_analyzer.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 11 #include "net/base/network_activity_monitor.h" | 11 #include "net/base/network_activity_monitor.h" |
| 12 #include "net/base/url_util.h" | 12 #include "net/base/url_util.h" |
| 13 #include "net/nqe/network_quality_estimator_params.h" | |
| 13 #include "net/url_request/url_request.h" | 14 #include "net/url_request/url_request.h" |
| 14 | 15 |
| 15 #if defined(OS_ANDROID) | 16 #if defined(OS_ANDROID) |
| 16 #include "net/android/traffic_stats.h" | 17 #include "net/android/traffic_stats.h" |
| 17 #endif // OS_ANDROID | 18 #endif // OS_ANDROID |
| 18 | 19 |
| 19 namespace net { | 20 namespace net { |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 23 // Maximum number of accuracy degrading requests, and requests that do not | 24 // Maximum number of accuracy degrading requests, and requests that do not |
| 24 // degrade accuracy held in the memory. | 25 // degrade accuracy held in the memory. |
| 25 static const size_t kMaxRequestsSize = 300; | 26 static const size_t kMaxRequestsSize = 300; |
| 26 | 27 |
| 27 // Tiny transfer sizes may give inaccurate throughput results. | 28 // Tiny transfer sizes may give inaccurate throughput results. |
| 28 // Minimum size of the transfer over which the throughput is computed. | 29 // Minimum size of the transfer over which the throughput is computed. |
| 29 static const int kMinTransferSizeInBits = 32 * 8 * 1000; | 30 static const int kMinTransferSizeInBits = 32 * 8 * 1000; |
| 30 | 31 |
| 31 } // namespace | 32 } // namespace |
| 32 | 33 |
| 33 namespace nqe { | 34 namespace nqe { |
| 34 | 35 |
| 35 namespace internal { | 36 namespace internal { |
| 36 | 37 |
| 37 ThroughputAnalyzer::ThroughputAnalyzer( | 38 ThroughputAnalyzer::ThroughputAnalyzer( |
| 39 const NetworkQualityEstimatorParams* params, | |
| 38 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 40 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 39 ThroughputObservationCallback throughput_observation_callback, | 41 ThroughputObservationCallback throughput_observation_callback, |
| 40 bool use_local_host_requests_for_tests, | 42 bool use_local_host_requests_for_tests, |
| 41 bool use_smaller_responses_for_tests) | 43 bool use_smaller_responses_for_tests) |
| 42 : task_runner_(task_runner), | 44 : params_(params), |
|
RyanSturm
2017/05/22 19:45:04
Do you plan to use this for other metrics? If not,
tbansal1
2017/05/22 19:58:01
Yes, I am going to do it for other metrics too.
RyanSturm
2017/05/22 20:14:40
Acknowledged.
| |
| 45 task_runner_(task_runner), | |
| 43 throughput_observation_callback_(throughput_observation_callback), | 46 throughput_observation_callback_(throughput_observation_callback), |
| 44 last_connection_change_(base::TimeTicks::Now()), | 47 last_connection_change_(base::TimeTicks::Now()), |
| 45 window_start_time_(base::TimeTicks()), | 48 window_start_time_(base::TimeTicks()), |
| 46 bits_received_at_window_start_(0), | 49 bits_received_at_window_start_(0), |
| 47 disable_throughput_measurements_(false), | 50 disable_throughput_measurements_(false), |
| 48 use_localhost_requests_for_tests_(use_local_host_requests_for_tests), | 51 use_localhost_requests_for_tests_(use_local_host_requests_for_tests), |
| 49 use_small_responses_for_tests_(use_smaller_responses_for_tests) { | 52 use_small_responses_for_tests_(use_smaller_responses_for_tests) { |
| 53 DCHECK(params_); | |
| 50 DCHECK(task_runner_); | 54 DCHECK(task_runner_); |
| 51 DCHECK(!IsCurrentlyTrackingThroughput()); | 55 DCHECK(!IsCurrentlyTrackingThroughput()); |
| 52 } | 56 } |
| 53 | 57 |
| 54 ThroughputAnalyzer::~ThroughputAnalyzer() { | 58 ThroughputAnalyzer::~ThroughputAnalyzer() { |
| 55 DCHECK(thread_checker_.CalledOnValidThread()); | 59 DCHECK(thread_checker_.CalledOnValidThread()); |
| 56 } | 60 } |
| 57 | 61 |
| 58 void ThroughputAnalyzer::MaybeStartThroughputObservationWindow() { | 62 void ThroughputAnalyzer::MaybeStartThroughputObservationWindow() { |
| 59 DCHECK(thread_checker_.CalledOnValidThread()); | 63 DCHECK(thread_checker_.CalledOnValidThread()); |
| 60 | 64 |
| 61 if (disable_throughput_measurements_) | 65 if (disable_throughput_measurements_) |
| 62 return; | 66 return; |
| 63 | 67 |
| 64 // Throughput observation window can be started only if no accuracy degrading | 68 // Throughput observation window can be started only if no accuracy degrading |
| 65 // requests are currently active, the observation window is not already | 69 // requests are currently active, the observation window is not already |
| 66 // started, and there is at least one active request that does not degrade | 70 // started, and there is at least one active request that does not degrade |
| 67 // throughput computation accuracy. | 71 // throughput computation accuracy. |
| 68 if (accuracy_degrading_requests_.size() > 0 || | 72 if (accuracy_degrading_requests_.size() > 0 || |
| 69 IsCurrentlyTrackingThroughput() || requests_.size() <= 0) { | 73 IsCurrentlyTrackingThroughput() || |
| 74 requests_.size() < params_->throughput_min_requests_in_flight()) { | |
| 70 return; | 75 return; |
| 71 } | 76 } |
| 72 window_start_time_ = base::TimeTicks::Now(); | 77 window_start_time_ = base::TimeTicks::Now(); |
| 73 bits_received_at_window_start_ = GetBitsReceived(); | 78 bits_received_at_window_start_ = GetBitsReceived(); |
| 74 } | 79 } |
| 75 | 80 |
| 76 void ThroughputAnalyzer::EndThroughputObservationWindow() { | 81 void ThroughputAnalyzer::EndThroughputObservationWindow() { |
| 77 DCHECK(thread_checker_.CalledOnValidThread()); | 82 DCHECK(thread_checker_.CalledOnValidThread()); |
| 78 | 83 |
| 79 // Mark the throughput observation window as stopped by resetting the window | 84 // Mark the throughput observation window as stopped by resetting the window |
| 80 // parameters. | 85 // parameters. |
| 81 window_start_time_ = base::TimeTicks(); | 86 window_start_time_ = base::TimeTicks(); |
| 82 bits_received_at_window_start_ = 0; | 87 bits_received_at_window_start_ = 0; |
| 83 } | 88 } |
| 84 | 89 |
| 85 bool ThroughputAnalyzer::IsCurrentlyTrackingThroughput() const { | 90 bool ThroughputAnalyzer::IsCurrentlyTrackingThroughput() const { |
| 86 DCHECK(thread_checker_.CalledOnValidThread()); | 91 DCHECK(thread_checker_.CalledOnValidThread()); |
| 87 | 92 |
| 88 if (window_start_time_.is_null()) | 93 if (window_start_time_.is_null()) |
| 89 return false; | 94 return false; |
| 90 | 95 |
| 91 // If the throughput observation window is running, then at least one request | 96 // If the throughput observation window is running, then at least one request |
| 92 // that does not degrade throughput computation accuracy should be active. | 97 // that does not degrade throughput computation accuracy should be active. |
| 93 DCHECK_GT(requests_.size(), 0U); | 98 DCHECK_GT(requests_.size(), 0U); |
| 94 | 99 |
| 95 // If the throughput observation window is running, then no accuracy degrading | 100 // If the throughput observation window is running, then no accuracy degrading |
| 96 // requests should be currently active. | 101 // requests should be currently active. |
| 97 DCHECK_EQ(0U, accuracy_degrading_requests_.size()); | 102 DCHECK_EQ(0U, accuracy_degrading_requests_.size()); |
| 98 | 103 |
| 104 DCHECK_LE(params_->throughput_min_requests_in_flight(), requests_.size()); | |
| 105 | |
| 99 return true; | 106 return true; |
| 100 } | 107 } |
| 101 | 108 |
| 102 void ThroughputAnalyzer::NotifyStartTransaction(const URLRequest& request) { | 109 void ThroughputAnalyzer::NotifyStartTransaction(const URLRequest& request) { |
| 103 DCHECK(thread_checker_.CalledOnValidThread()); | 110 DCHECK(thread_checker_.CalledOnValidThread()); |
| 104 | 111 |
| 105 if (disable_throughput_measurements_) | 112 if (disable_throughput_measurements_) |
| 106 return; | 113 return; |
| 107 | 114 |
| 108 const bool degrades_accuracy = DegradesAccuracy(request); | 115 const bool degrades_accuracy = DegradesAccuracy(request); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 134 | 141 |
| 135 // Return early if the |request| is not present in the collections of | 142 // Return early if the |request| is not present in the collections of |
| 136 // requests. This may happen when a completed request is later destroyed. | 143 // requests. This may happen when a completed request is later destroyed. |
| 137 if (requests_.find(&request) == requests_.end() && | 144 if (requests_.find(&request) == requests_.end() && |
| 138 accuracy_degrading_requests_.find(&request) == | 145 accuracy_degrading_requests_.find(&request) == |
| 139 accuracy_degrading_requests_.end()) { | 146 accuracy_degrading_requests_.end()) { |
| 140 return; | 147 return; |
| 141 } | 148 } |
| 142 | 149 |
| 143 int32_t downstream_kbps; | 150 int32_t downstream_kbps; |
| 144 if (MayBeGetThroughputObservation(&downstream_kbps)) { | 151 if (MayBeGetThroughputObservation(&downstream_kbps)) { |
|
RyanSturm
2017/05/22 20:14:40
nit please: Change the name of this to s/MayBeGetT
tbansal1
2017/05/22 22:51:55
Done.
| |
| 145 // Notify the provided callback. | 152 // Notify the provided callback. |
| 146 task_runner_->PostTask( | 153 task_runner_->PostTask( |
| 147 FROM_HERE, | 154 FROM_HERE, |
| 148 base::Bind(throughput_observation_callback_, downstream_kbps)); | 155 base::Bind(throughput_observation_callback_, downstream_kbps)); |
| 149 } | 156 } |
| 150 | 157 |
| 151 // Try to remove the request from either |accuracy_degrading_requests_| or | 158 // Try to remove the request from either |accuracy_degrading_requests_| or |
| 152 // |requests_|, since it is no longer active. | 159 // |requests_|, since it is no longer active. |
| 153 if (accuracy_degrading_requests_.erase(&request) == 1u) { | 160 if (accuracy_degrading_requests_.erase(&request) == 1u) { |
| 154 // |request| cannot be in both |accuracy_degrading_requests_| and | 161 // |request| cannot be in both |accuracy_degrading_requests_| and |
| 155 // |requests_| at the same time. | 162 // |requests_| at the same time. |
| 156 DCHECK(requests_.end() == requests_.find(&request)); | 163 DCHECK(requests_.end() == requests_.find(&request)); |
| 157 | 164 |
| 158 // If a request that degraded the accuracy of throughput computation has | 165 // If a request that degraded the accuracy of throughput computation has |
| 159 // completed, then it may be possible to start the tracking window. | 166 // completed, then it may be possible to start the tracking window. |
| 160 MaybeStartThroughputObservationWindow(); | 167 MaybeStartThroughputObservationWindow(); |
| 161 return; | 168 return; |
| 162 } | 169 } |
| 163 | 170 |
| 164 if (requests_.erase(&request) == 1u) { | 171 if (requests_.erase(&request) == 1u) { |
| 165 // If there is no network activity, stop tracking throughput to prevent | 172 // If there is no network activity, stop tracking throughput to prevent |
| 166 // recording of any observations. | 173 // recording of any observations. |
| 167 if (requests_.size() == 0) | 174 if (requests_.size() < params_->throughput_min_requests_in_flight()) |
| 168 EndThroughputObservationWindow(); | 175 EndThroughputObservationWindow(); |
| 169 return; | 176 return; |
| 170 } | 177 } |
| 171 // |request| must be either in |accuracy_degrading_requests_| or |requests_|. | 178 // |request| must be either in |accuracy_degrading_requests_| or |requests_|. |
| 172 NOTREACHED(); | 179 NOTREACHED(); |
| 173 } | 180 } |
| 174 | 181 |
| 175 bool ThroughputAnalyzer::MayBeGetThroughputObservation( | 182 bool ThroughputAnalyzer::MayBeGetThroughputObservation( |
| 176 int32_t* downstream_kbps) { | 183 int32_t* downstream_kbps) { |
| 177 DCHECK(thread_checker_.CalledOnValidThread()); | 184 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 // TODO(tbansal): crbug.com/609174 Add UMA to record how frequently this | 297 // TODO(tbansal): crbug.com/609174 Add UMA to record how frequently this |
| 291 // happens. | 298 // happens. |
| 292 } | 299 } |
| 293 } | 300 } |
| 294 | 301 |
| 295 } // namespace internal | 302 } // namespace internal |
| 296 | 303 |
| 297 } // namespace nqe | 304 } // namespace nqe |
| 298 | 305 |
| 299 } // namespace net | 306 } // namespace net |
| OLD | NEW |