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

Unified Diff: chrome/browser/devtools/devtools_network_interceptor.cc

Issue 346503002: DevTools: emulate latency network condition. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@twin
Patch Set: Rebase Created 6 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
Index: chrome/browser/devtools/devtools_network_interceptor.cc
diff --git a/chrome/browser/devtools/devtools_network_interceptor.cc b/chrome/browser/devtools/devtools_network_interceptor.cc
index 0399b8d4038358f95ec729629e3bce9245883f68..31cc5aacce465938b0725d8b972982ec75996584 100644
--- a/chrome/browser/devtools/devtools_network_interceptor.cc
+++ b/chrome/browser/devtools/devtools_network_interceptor.cc
@@ -4,9 +4,12 @@
#include "chrome/browser/devtools/devtools_network_interceptor.h"
+#include <limits>
+
#include "base/time/time.h"
#include "chrome/browser/devtools/devtools_network_conditions.h"
#include "chrome/browser/devtools/devtools_network_transaction.h"
+#include "net/base/load_timing_info.h"
namespace {
@@ -41,24 +44,36 @@ void DevToolsNetworkInterceptor::RemoveTransaction(
if (!conditions_->IsThrottling())
return;
- UpdateThrottles();
+ base::TimeTicks now = base::TimeTicks::Now();
+ UpdateThrottledTransactions(now);
throttled_transactions_.erase(std::remove(throttled_transactions_.begin(),
throttled_transactions_.end(), transaction),
throttled_transactions_.end());
- ArmTimer();
+
+ SuspendedTransactions::iterator it = suspended_transactions_.begin();
+ for (; it != suspended_transactions_.end(); ++it) {
+ if (it->first == transaction) {
+ suspended_transactions_.erase(it);
+ break;
+ }
+ }
+
+ ArmTimer(now);
}
void DevToolsNetworkInterceptor::UpdateConditions(
const scoped_refptr<DevToolsNetworkConditions> conditions) {
DCHECK(conditions);
+ base::TimeTicks now = base::TimeTicks::Now();
if (conditions_->IsThrottling())
- UpdateThrottles();
+ UpdateThrottledTransactions(now);
conditions_ = conditions;
if (conditions->offline()) {
timer_.Stop();
throttled_transactions_.clear();
+ suspended_transactions_.clear();
Transactions old_transactions(transactions_);
Transactions::iterator it = old_transactions.begin();
for (;it != old_transactions.end(); ++it) {
@@ -74,7 +89,7 @@ void DevToolsNetworkInterceptor::UpdateConditions(
if (conditions->IsThrottling()) {
DCHECK(conditions->download_throughput() != 0);
- offset_ = base::TimeTicks::Now();
+ offset_ = now;
last_tick_ = 0;
int64_t us_tick_length =
(1000000L * kPacketSize) / conditions->download_throughput();
@@ -82,24 +97,46 @@ void DevToolsNetworkInterceptor::UpdateConditions(
if (us_tick_length == 0)
us_tick_length = 1;
tick_length_ = base::TimeDelta::FromMicroseconds(us_tick_length);
- ArmTimer();
+ latency_length_ = base::TimeDelta();
+ double latency = conditions_->latency();
+ if (latency > 0)
+ latency_length_ = base::TimeDelta::FromMillisecondsD(latency);
+ ArmTimer(now);
} else {
timer_.Stop();
- int64_t length = throttled_transactions_.size();
- for (int64_t i = 0; i < length; ++i)
- throttled_transactions_[i]->FireThrottledCallback();
- throttled_transactions_.clear();
+
+ std::vector<DevToolsNetworkTransaction*> throttled_transactions;
+ throttled_transactions.swap(throttled_transactions_);
+ size_t throttle_count = throttled_transactions.size();
+ for (size_t i = 0; i < throttle_count; ++i) {
+ DevToolsNetworkTransaction* transaction = throttled_transactions[i];
+ if (transactions_.find(transaction) != transactions_.end())
+ transaction->FireThrottledCallback();
+ }
+
+ SuspendedTransactions suspended_transactions;
+ suspended_transactions_.swap(suspended_transactions_);
+ size_t suspend_count = suspended_transactions.size();
+ for (size_t i = 0; i < suspend_count; ++i) {
+ DevToolsNetworkTransaction* transaction =
+ suspended_transactions[i].first;
+ if (transactions_.find(transaction) != transactions_.end())
+ transaction->FireThrottledCallback();
+ }
}
}
-void DevToolsNetworkInterceptor::UpdateThrottles() {
- int64_t last_tick = (base::TimeTicks::Now() - offset_) / tick_length_;
+void DevToolsNetworkInterceptor::UpdateThrottledTransactions(
+ base::TimeTicks now) {
+ int64_t last_tick = (now - offset_) / tick_length_;
int64_t ticks = last_tick - last_tick_;
last_tick_ = last_tick;
int64_t length = throttled_transactions_.size();
- if (!length)
+ if (!length) {
+ UpdateSuspendedTransactions(now);
return;
+ }
int64_t shift = ticks % length;
for (int64_t i = 0; i < length; ++i) {
@@ -108,10 +145,28 @@ void DevToolsNetworkInterceptor::UpdateThrottles() {
}
std::rotate(throttled_transactions_.begin(),
throttled_transactions_.begin() + shift, throttled_transactions_.end());
+
+ UpdateSuspendedTransactions(now);
+}
+
+void DevToolsNetworkInterceptor::UpdateSuspendedTransactions(
+ base::TimeTicks now) {
+ int64_t activation_baseline =
+ (now - latency_length_ - base::TimeTicks()).InMicroseconds();
+ SuspendedTransactions suspended_transactions;
+ SuspendedTransactions::iterator it = suspended_transactions_.begin();
+ for (; it != suspended_transactions_.end(); ++it) {
+ if (it->second <= activation_baseline)
+ throttled_transactions_.push_back(it->first);
+ else
+ suspended_transactions.push_back(*it);
+ }
+ suspended_transactions_.swap(suspended_transactions);
}
void DevToolsNetworkInterceptor::OnTimer() {
- UpdateThrottles();
+ base::TimeTicks now = base::TimeTicks::Now();
+ UpdateThrottledTransactions(now);
std::vector<DevToolsNetworkTransaction*> active_transactions;
std::vector<DevToolsNetworkTransaction*> finished_transactions;
@@ -128,36 +183,64 @@ void DevToolsNetworkInterceptor::OnTimer() {
for (size_t i = 0; i < length; ++i)
finished_transactions[i]->FireThrottledCallback();
- ArmTimer();
+ ArmTimer(now);
}
-void DevToolsNetworkInterceptor::ArmTimer() {
- size_t length = throttled_transactions_.size();
- if (!length)
+void DevToolsNetworkInterceptor::ArmTimer(base::TimeTicks now) {
+ size_t throttle_count = throttled_transactions_.size();
+ size_t suspend_count = suspended_transactions_.size();
+ if (!throttle_count && !suspend_count)
return;
int64_t min_ticks_left = 0x10000L;
- for (size_t i = 0; i < length; ++i) {
+ for (size_t i = 0; i < throttle_count; ++i) {
int64_t packets_left = (throttled_transactions_[i]->throttled_byte_count() +
kPacketSize - 1) / kPacketSize;
- int64_t ticks_left = (i + 1) + length * (packets_left - 1);
+ int64_t ticks_left = (i + 1) + throttle_count * (packets_left - 1);
if (i == 0 || ticks_left < min_ticks_left)
min_ticks_left = ticks_left;
}
base::TimeTicks desired_time =
offset_ + tick_length_ * (last_tick_ + min_ticks_left);
+
+ int64_t min_baseline = std::numeric_limits<int64>::max();
+ for (size_t i = 0; i < suspend_count; ++i) {
+ if (suspended_transactions_[i].second < min_baseline)
+ min_baseline = suspended_transactions_[i].second;
+ }
+ if (suspend_count) {
+ base::TimeTicks activation_time = base::TimeTicks() +
+ base::TimeDelta::FromMicroseconds(min_baseline) + latency_length_;
+ if (activation_time < desired_time)
+ desired_time = activation_time;
+ }
+
timer_.Start(
FROM_HERE,
- desired_time - base::TimeTicks::Now(),
+ desired_time - now,
base::Bind(
&DevToolsNetworkInterceptor::OnTimer,
base::Unretained(this)));
}
void DevToolsNetworkInterceptor::ThrottleTransaction(
- DevToolsNetworkTransaction* transaction) {
- UpdateThrottles();
- throttled_transactions_.push_back(transaction);
- ArmTimer();
+ DevToolsNetworkTransaction* transaction, bool start) {
+ base::TimeTicks now = base::TimeTicks::Now();
+ UpdateThrottledTransactions(now);
+ if (start && latency_length_ != base::TimeDelta()) {
+ net::LoadTimingInfo load_timing_info;
+ base::TimeTicks send_end;
+ if (transaction->GetLoadTimingInfo(&load_timing_info))
+ send_end = load_timing_info.send_end;
+ if (send_end.is_null())
+ send_end = now;
+ int64_t us_send_end = (send_end - base::TimeTicks()).InMicroseconds();
+ suspended_transactions_.push_back(
+ SuspendedTransaction(transaction, us_send_end));
+ UpdateSuspendedTransactions(now);
+ } else {
+ throttled_transactions_.push_back(transaction);
+ }
+ ArmTimer(now);
}
bool DevToolsNetworkInterceptor::ShouldFail(
« no previous file with comments | « chrome/browser/devtools/devtools_network_interceptor.h ('k') | chrome/browser/devtools/devtools_network_transaction.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698