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

Unified Diff: webrtc/p2p/base/p2ptransportchannel.cc

Issue 2143653005: Dampening connection switch. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Address comments Created 4 years, 5 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: webrtc/p2p/base/p2ptransportchannel.cc
diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc
index 4ebd3a41c44612585ba4340a34d816e5e77fe167..e43853763e17a7269aa6f45d22aa69abe93cf9dd 100644
--- a/webrtc/p2p/base/p2ptransportchannel.cc
+++ b/webrtc/p2p/base/p2ptransportchannel.cc
@@ -80,6 +80,8 @@ const int STABLE_WRITABLE_CONNECTION_PING_INTERVAL = 2500; // ms
static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms
+static const int RECEIVING_SWITCHING_DELAY = 900; // ms
pthatcher1 2016/07/14 18:01:44 I don't quite follow the distinction between 900ms
+
// We periodically check if any existing networks do not have any connection
// and regather on those networks.
static const int DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000;
@@ -112,7 +114,8 @@ P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
false /* prioritize_most_likely_candidate_pairs */,
STABLE_WRITABLE_CONNECTION_PING_INTERVAL,
true /* presume_writable_when_fully_relayed */,
- DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL) {
+ DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL,
+ RECEIVING_SWITCHING_DELAY) {
uint32_t weak_ping_interval = ::strtoul(
webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(),
nullptr, 10);
@@ -184,7 +187,7 @@ void P2PTransportChannel::AddConnection(Connection* connection) {
// TODO(honghaiz): Stop the aggressive nomination on the controlling side and
// implement the ice-renomination option.
bool P2PTransportChannel::ShouldSwitchSelectedConnection(
- Connection* new_connection) const {
+ Connection* new_connection) {
if (!new_connection || selected_connection_ == new_connection) {
return false;
}
@@ -193,7 +196,20 @@ bool P2PTransportChannel::ShouldSwitchSelectedConnection(
return true;
}
- int cmp = CompareConnections(selected_connection_, new_connection);
+ bool switching_dampened = false;
+ int64_t new_conn_receiving_threshold =
+ (*config_.receiving_switching_delay) +
pthatcher1 2016/07/14 18:01:44 Don't we have to make sure config_.receiving_switc
honghaiz3 2016/07/14 23:15:01 We set the default value at the beginning and only
+ new_connection->continuously_receiving_since();
pthatcher1 2016/07/14 18:01:44 I was thinking of it the other way around: int64_
honghaiz3 2016/07/14 23:15:01 Done. If it is not set, it will just get a default
+ int cmp =
+ CompareConnections(selected_connection_, new_connection,
+ new_conn_receiving_threshold, &switching_dampened);
+ // If a connection switching is dampened, the new connection is in a better
+ // receiving state than the currently selected connection. So we need to
+ // re-check whether it needs to be switched at a later time.
+ if (switching_dampened && cmp >= 0) {
+ thread()->PostDelayed(RTC_FROM_HERE, *config_.receiving_switching_delay,
+ this, MSG_SORT_AND_UPDATE_STATE);
+ }
pthatcher1 2016/07/14 18:01:44 If ShoudlSwitchSelectedConnection also takes/retur
honghaiz3 2016/07/14 23:15:01 Done.
if (cmp != 0) {
return cmp < 0;
}
@@ -369,6 +385,11 @@ void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
LOG(LS_INFO) << "Set regather_on_failed_networks_interval to "
<< *config_.regather_on_failed_networks_interval;
}
+ if (config.receiving_switching_delay) {
+ config_.receiving_switching_delay = config.receiving_switching_delay;
+ LOG(LS_INFO) << "Set receiving_switching_delay to"
+ << *config_.receiving_switching_delay;
+ }
}
const IceConfig& P2PTransportChannel::config() const {
@@ -635,8 +656,7 @@ void P2PTransportChannel::OnNominated(Connection* conn) {
}
LOG(LS_INFO)
- << "Switching selected connection on controlled side due to nomination: "
- << conn->ToString();
+ << "Switching selected connection on controlled side due to nomination";
SwitchSelectedConnection(conn);
// Now that we have selected a connection, it is time to prune other
// connections and update the read/write state of the channel.
@@ -956,6 +976,19 @@ void P2PTransportChannel::UpdateConnectionStates() {
for (Connection* c : connections_) {
c->UpdateState(now);
}
+ if (!selected_connection_) {
+ was_strong_ = false;
+ return;
+ }
+ bool is_strong = !selected_connection_->weak();
+ if (was_strong_ && !is_strong) {
+ // If the selected connection just changes to weak,
+ // reset the continuously_receiving_since time for each connection.
+ for (Connection* c : connections_) {
+ c->reset_continuously_receiving_since(now);
pthatcher1 2016/07/14 18:01:44 I don't think we need this. Won't the dampening w
+ }
+ }
+ was_strong_ = is_strong;
}
// Prepare for best candidate sorting.
@@ -987,8 +1020,11 @@ void P2PTransportChannel::MaybeStartPinging() {
// Compare two connections based on their writing, receiving, and connected
// states.
-int P2PTransportChannel::CompareConnectionStates(const Connection* a,
- const Connection* b) const {
+int P2PTransportChannel::CompareConnectionStates(
+ const Connection* a,
+ const Connection* b,
+ int64_t b_receiving_threshold,
+ bool* switching_dampened) const {
// First, prefer a connection that's writable or presumed writable over
// one that's not writable.
bool a_writable = a->writable() || PresumedWritable(a);
@@ -1000,22 +1036,24 @@ int P2PTransportChannel::CompareConnectionStates(const Connection* a,
return b_is_better;
}
- // Sort based on write-state. Better states have lower values.
- if (a->write_state() < b->write_state()) {
- return a_is_better;
- }
- if (b->write_state() < a->write_state()) {
- return b_is_better;
+ // Better write-states have lower values, and a negative return value
+ // indicates b is better.
+ int cmp = b->write_state() - a->write_state();
+ if (cmp != 0) {
+ return cmp;
}
pthatcher1 2016/07/14 18:01:44 Might as well just leave this part unchanged, sinc
honghaiz3 2016/07/14 23:15:01 Done.
// We prefer a receiving connection to a non-receiving, higher-priority
- // connection when sorting connections and choosing which connection to
- // switch to.
+ // connection when sorting connections.
if (a->receiving() && !b->receiving()) {
return a_is_better;
}
if (!a->receiving() && b->receiving()) {
- return b_is_better;
+ if (b_receiving_threshold == 0 ||
+ rtc::TimeMillis() >= b_receiving_threshold) {
pthatcher1 2016/07/14 18:01:44 With my alternate definition of "threshold", this
honghaiz3 2016/07/14 23:15:01 Done. Use an optional now. We still need to check
+ return b_is_better;
+ }
+ *switching_dampened = true;
}
// WARNING: Some complexity here about TCP reconnecting.
@@ -1083,14 +1121,17 @@ int P2PTransportChannel::CompareConnectionCandidates(
}
int P2PTransportChannel::CompareConnections(const Connection* a,
- const Connection* b) const {
+ const Connection* b,
+ int64_t b_receiving_threshold,
+ bool* switching_dampened) const {
RTC_CHECK(a != nullptr);
RTC_CHECK(b != nullptr);
// We prefer to switch to a writable and receiving connection over a
// non-writable or non-receiving connection, even if the latter has
// been nominated by the controlling side.
- int state_cmp = CompareConnectionStates(a, b);
+ int state_cmp =
+ CompareConnectionStates(a, b, b_receiving_threshold, switching_dampened);
if (state_cmp != 0) {
return state_cmp;
}
@@ -1143,11 +1184,10 @@ void P2PTransportChannel::SortConnectionsAndUpdateState() {
// need to consider switching to.
std::stable_sort(connections_.begin(), connections_.end(),
[this](const Connection* a, const Connection* b) {
- int cmp = CompareConnections(a, b);
+ int cmp = CompareConnections(a, b, 0, nullptr);
if (cmp != 0) {
return cmp > 0;
}
-
// Otherwise, sort based on latency estimate.
return a->rtt() < b->rtt();
});
@@ -1165,8 +1205,7 @@ void P2PTransportChannel::SortConnectionsAndUpdateState() {
// have to be writable to become the selected connection although it will
// have higher priority if it is writable.
if (ShouldSwitchSelectedConnection(top_connection)) {
- LOG(LS_INFO) << "Switching selected connection after sorting: "
- << top_connection->ToString();
+ LOG(LS_INFO) << "Switching selected connection after sorting";
SwitchSelectedConnection(top_connection);
}
@@ -1415,6 +1454,7 @@ void P2PTransportChannel::OnCheckAndPing() {
// Make sure the states of the connections are up-to-date (since this affects
// which ones are pingable).
UpdateConnectionStates();
+
// When the selected connection is not receiving or not writable, or any
// active connection has not been pinged enough times, use the weak ping
// interval.
@@ -1622,7 +1662,7 @@ void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
// we can just set selected to nullptr and re-choose a best assuming that
// there was no selected connection.
if (selected_connection_ == connection) {
- LOG(LS_INFO) << "selected connection destroyed. Will choose a new one.";
+ LOG(LS_INFO) << "Selected connection destroyed. Will choose a new one.";
SwitchSelectedConnection(nullptr);
RequestSortAndStateUpdate();
} else {
@@ -1729,7 +1769,7 @@ void P2PTransportChannel::OnReadPacket(Connection* connection,
if (ice_role_ == ICEROLE_CONTROLLED &&
ShouldSwitchSelectedConnection(connection)) {
LOG(LS_INFO) << "Switching selected connection on controlled side due to "
- << "data received: " << connection->ToString();
+ << "data received";
SwitchSelectedConnection(connection);
}
}

Powered by Google App Engine
This is Rietveld 408576698