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

Unified Diff: content/renderer/scheduler/throttled_message_sender.cc

Issue 847883002: Reland "Throttle resource message requests during user interaction" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tweak Created 5 years, 11 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: content/renderer/scheduler/throttled_message_sender.cc
diff --git a/content/renderer/scheduler/throttled_message_sender.cc b/content/renderer/scheduler/throttled_message_sender.cc
new file mode 100644
index 0000000000000000000000000000000000000000..242d4105b1616949cfe72de8326f5f8c8456464a
--- /dev/null
+++ b/content/renderer/scheduler/throttled_message_sender.cc
@@ -0,0 +1,116 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/scheduler/throttled_message_sender.h"
+
+#include "base/auto_reset.h"
+#include "content/renderer/scheduler/renderer_scheduler.h"
+#include "ipc/ipc_message.h"
+
+namespace content {
+namespace {
+
+const int kReasonableFlushesPerSecond = 60;
picksi1 2015/01/13 11:24:44 Is this 60 related to the 60*4 in kMaxResourceMess
jdduke (slow) 2015/01/13 16:18:11 It's not really related, but I'll add a comment.
+
+} // namespace
+
+ThrottledMessageSender::ThrottledMessageSender(IPC::Sender* proxied_sender,
+ RendererScheduler* scheduler,
+ int max_sent_messages_per_second)
+ : proxied_sender_(proxied_sender),
+ scheduler_(scheduler),
+ max_sent_messages_per_flush_(
+ std::max(1,
+ max_sent_messages_per_second / kReasonableFlushesPerSecond)),
+ flush_period_(base::TimeDelta::FromSecondsD(
+ 1.f /
+ std::min(max_sent_messages_per_second, kReasonableFlushesPerSecond))),
+ sent_messages_since_last_flush_(0),
+ flush_timer_(FROM_HERE,
Sami 2015/01/13 14:47:35 I wonder if we should build some kind of use-idle-
rmcilroy 2015/01/13 15:24:37 I like this idea (if not the name... ;). How abou
jdduke (slow) 2015/01/13 16:18:11 All solid options, I'm open to whatever you all th
+ flush_period_,
+ base::Bind(&ThrottledMessageSender::FlushThrottled,
+ base::Unretained(this)),
+ false /* is_repeating */),
+ is_sending_via_proxied_(false) {
+ DCHECK(proxied_sender);
+ DCHECK(scheduler);
+ DCHECK_GT(max_sent_messages_per_second, 0);
+ flush_timer_.SetTaskRunner(scheduler->DefaultTaskRunner());
+}
+
+ThrottledMessageSender::~ThrottledMessageSender() {
+ FlushAll();
+ DCHECK(throttled_messages_.empty());
+}
+
+bool ThrottledMessageSender::Send(IPC::Message* msg) {
+ DCHECK(!is_sending_via_proxied_);
+ thread_checker_.CalledOnValidThread();
+
+ if (msg->is_sync()) {
+ FlushAll();
+ return SendViaProxiedSender(msg);
+ }
+
+ if (!throttled_messages_.empty()) {
+ throttled_messages_.push_back(msg);
picksi1 2015/01/13 11:24:44 cunning!
+ return true;
+ }
+
+ if (!scheduler_->ShouldYieldForHighPriorityWork())
alex clarke (OOO till 29th) 2015/01/13 10:38:02 I think you'd get better results if the scheduler
Sami 2015/01/13 14:47:35 What advantage were you thinking of? This feels li
rmcilroy 2015/01/13 15:24:37 I agree with Sami here - I think this shouldn't be
alex clarke (OOO till 29th) 2015/01/13 15:46:55 As far as I understand it, the intent here is to t
jdduke (slow) 2015/01/13 16:18:11 I agree with Alex here, and was actually going to
+ return SendViaProxiedSender(msg);
+
+ if (Now() > (last_sent_message_time_ + flush_period_)) {
+ // If sufficient time has passed since the previous send, we can effectively
+ // mark the pipeline as flushed.
+ sent_messages_since_last_flush_ = 0;
+ return SendViaProxiedSender(msg);
+ }
+
+ if (sent_messages_since_last_flush_ < max_sent_messages_per_flush_)
+ return SendViaProxiedSender(msg);
+
+ throttled_messages_.push_back(msg);
+ DCHECK(!flush_timer_.IsRunning());
+ flush_timer_.Reset();
+ return true;
+}
+
+base::TimeTicks ThrottledMessageSender::Now() const {
+ return base::TimeTicks::Now();
+}
+
+void ThrottledMessageSender::FlushAll() {
+ sent_messages_since_last_flush_ = 0;
picksi1 2015/01/13 11:24:44 Can you confirm that there are no threading issues
jdduke (slow) 2015/01/13 16:18:11 Yeah, I've got the |DCHECK(!is_sending_via_proxied
+ flush_timer_.Stop();
+
+ for (auto& msg : throttled_messages_)
+ SendViaProxiedSender(msg);
+ throttled_messages_.clear();
+}
+
+void ThrottledMessageSender::FlushThrottled() {
+ sent_messages_since_last_flush_ = 0;
+
+ while (!throttled_messages_.empty() &&
picksi1 2015/01/13 11:24:44 Suggestion for discussion: Rather than checking fo
jdduke (slow) 2015/01/13 16:18:11 That's a solid option, though it would prevent the
+ sent_messages_since_last_flush_ < max_sent_messages_per_flush_) {
+ IPC::Message* msg = throttled_messages_.front();
+ throttled_messages_.pop_front();
+ SendViaProxiedSender(msg);
Sami 2015/01/13 14:47:35 Should we yield here too (after sending at least o
jdduke (slow) 2015/01/13 16:18:11 Hmm, the |Send| itself should be fairly cheap (max
+ }
+
+ if (!throttled_messages_.empty())
+ flush_timer_.Reset();
+}
+
+bool ThrottledMessageSender::SendViaProxiedSender(IPC::Message* msg) {
+ DCHECK(!is_sending_via_proxied_);
+ base::AutoReset<bool> is_sending_via_proxied_resetter(
+ &is_sending_via_proxied_, true);
+ last_sent_message_time_ = Now();
+ ++sent_messages_since_last_flush_;
+ return proxied_sender_->Send(msg);
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698