Add circuit-breaker in PacingController.
Some cases have been observer where the pacing controlled might have been stuck in a send-loop. This CL adds a circuit breaker that attempts to break that, and provide some logging for debugging. Bug: webrtc:11340 Change-Id: Ia3d3a44c2d897260ef23160ea7122c0d0f9baa79 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259521 Reviewed-by: Emil Lundmark <lndmrk@webrtc.org> Commit-Queue: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36592}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
22d094d4c9
commit
ed21d96e13
@ -193,7 +193,15 @@ void PacingController::SetProbingEnabled(bool enabled) {
|
||||
|
||||
void PacingController::SetPacingRates(DataRate pacing_rate,
|
||||
DataRate padding_rate) {
|
||||
RTC_DCHECK_GT(pacing_rate, DataRate::Zero());
|
||||
static constexpr DataRate kMaxRate = DataRate::KilobitsPerSec(100'000);
|
||||
RTC_CHECK_GT(pacing_rate, DataRate::Zero());
|
||||
RTC_CHECK_GE(padding_rate, DataRate::Zero());
|
||||
if (pacing_rate > kMaxRate || padding_rate > kMaxRate) {
|
||||
RTC_LOG(LS_WARNING) << "Very high pacing rates ( > " << kMaxRate.kbps()
|
||||
<< " kbps) configured: pacing = " << pacing_rate.kbps()
|
||||
<< " kbps, padding = " << padding_rate.kbps()
|
||||
<< " kbps.";
|
||||
}
|
||||
media_rate_ = pacing_rate;
|
||||
padding_rate_ = padding_rate;
|
||||
pacing_bitrate_ = pacing_rate;
|
||||
@ -478,7 +486,12 @@ void PacingController::ProcessPackets() {
|
||||
}
|
||||
|
||||
DataSize data_sent = DataSize::Zero();
|
||||
while (true) {
|
||||
// Circuit breaker, making sure main loop isn't forever.
|
||||
static constexpr int kMaxIterations = 1 << 16;
|
||||
int iteration = 0;
|
||||
int packets_sent = 0;
|
||||
int padding_packets_generated = 0;
|
||||
for (; iteration < kMaxIterations; ++iteration) {
|
||||
// Fetch packet, so long as queue is not empty or budget is not
|
||||
// exhausted.
|
||||
std::unique_ptr<RtpPacketToSend> rtp_packet =
|
||||
@ -490,6 +503,7 @@ void PacingController::ProcessPackets() {
|
||||
std::vector<std::unique_ptr<RtpPacketToSend>> padding_packets =
|
||||
packet_sender_->GeneratePadding(padding_to_add);
|
||||
if (!padding_packets.empty()) {
|
||||
padding_packets_generated += padding_packets.size();
|
||||
for (auto& packet : padding_packets) {
|
||||
EnqueuePacket(std::move(packet));
|
||||
}
|
||||
@ -520,6 +534,7 @@ void PacingController::ProcessPackets() {
|
||||
EnqueuePacket(std::move(packet));
|
||||
}
|
||||
data_sent += packet_size;
|
||||
++packets_sent;
|
||||
|
||||
// Send done, update send time.
|
||||
OnPacketSent(packet_type, packet_size, now);
|
||||
@ -546,6 +561,19 @@ void PacingController::ProcessPackets() {
|
||||
}
|
||||
}
|
||||
|
||||
if (iteration >= kMaxIterations) {
|
||||
// Circuit break activated. Log warning, adjust send time and return.
|
||||
// TODO(sprang): Consider completely clearing state.
|
||||
RTC_LOG(LS_ERROR) << "PacingController exceeded max iterations in "
|
||||
"send-loop: packets sent = "
|
||||
<< packets_sent << ", padding packets generated = "
|
||||
<< padding_packets_generated
|
||||
<< ", bytes sent = " << data_sent.bytes();
|
||||
last_send_time_ = now;
|
||||
last_process_time_ = now;
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_probing) {
|
||||
probing_send_failure_ = data_sent == DataSize::Zero();
|
||||
if (!probing_send_failure_) {
|
||||
|
Reference in New Issue
Block a user