Commit da009d15 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

Implment ThrottlingPolicy on ResourceLoadScheduler

This CL tightens the throttling policy initially (if certain
conditions are met), and loosen the policy when
Document::WillInsertBody is called.

Bug: 785770
Change-Id: I1fea7ced1105f48dabb25a68a546fd281db5e6eb
Reviewed-on: https://chromium-review.googlesource.com/799517
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Reviewed-by: default avatarTakashi Toyoshima <toyoshim@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521248}
parent 891184d0
...@@ -3088,6 +3088,10 @@ void Document::setBody(HTMLElement* prp_new_body, ...@@ -3088,6 +3088,10 @@ void Document::setBody(HTMLElement* prp_new_body,
void Document::WillInsertBody() { void Document::WillInsertBody() {
if (GetFrame()) if (GetFrame())
GetFrame()->Client()->DispatchWillInsertBody(); GetFrame()->Client()->DispatchWillInsertBody();
if (auto* loader = Loader())
loader->Fetcher()->LoosenLoadThrottlingPolicy();
// If we get to the <body> try to resume commits since we should have content // If we get to the <body> try to resume commits since we should have content
// to paint now. // to paint now.
// TODO(esprehn): Is this really optimal? We might start producing frames // TODO(esprehn): Is this really optimal? We might start producing frames
......
...@@ -157,6 +157,13 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext { ...@@ -157,6 +157,13 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext {
const ResourceRequest&, const ResourceRequest&,
scoped_refptr<WebTaskRunner>) override; scoped_refptr<WebTaskRunner>) override;
ResourceLoadScheduler::ThrottlingPolicy InitialLoadThrottlingPolicy()
const override {
// Frame loading should normally start with |kTight| throttling, as the
// frame will be in layout-blocking state until the <body> tag is inserted.
return ResourceLoadScheduler::ThrottlingPolicy::kTight;
}
bool IsDetached() const override { return frozen_state_; } bool IsDetached() const override { return frozen_state_; }
FetchContext* Detach() override; FetchContext* Detach() override;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "platform/loader/fetch/FetchParameters.h" #include "platform/loader/fetch/FetchParameters.h"
#include "platform/loader/fetch/Resource.h" #include "platform/loader/fetch/Resource.h"
#include "platform/loader/fetch/ResourceLoadPriority.h" #include "platform/loader/fetch/ResourceLoadPriority.h"
#include "platform/loader/fetch/ResourceLoadScheduler.h"
#include "platform/loader/fetch/ResourceRequest.h" #include "platform/loader/fetch/ResourceRequest.h"
#include "platform/network/ContentSecurityPolicyParsers.h" #include "platform/network/ContentSecurityPolicyParsers.h"
#include "platform/weborigin/SecurityViolationReportingPolicy.h" #include "platform/weborigin/SecurityViolationReportingPolicy.h"
...@@ -234,6 +235,13 @@ class PLATFORM_EXPORT FetchContext ...@@ -234,6 +235,13 @@ class PLATFORM_EXPORT FetchContext
return nullptr; return nullptr;
} }
// Returns the initial throttling policy used by the associated
// ResourceLoadScheduler.
virtual ResourceLoadScheduler::ThrottlingPolicy InitialLoadThrottlingPolicy()
const {
return ResourceLoadScheduler::ThrottlingPolicy::kNormal;
}
virtual bool IsDetached() const { return false; } virtual bool IsDetached() const { return false; }
// Obtains WebFrameScheduler instance that is used in the attached frame. // Obtains WebFrameScheduler instance that is used in the attached frame.
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include "platform/loader/fetch/Resource.h" #include "platform/loader/fetch/Resource.h"
#include "platform/loader/fetch/ResourceError.h" #include "platform/loader/fetch/ResourceError.h"
#include "platform/loader/fetch/ResourceLoadPriority.h" #include "platform/loader/fetch/ResourceLoadPriority.h"
#include "platform/loader/fetch/ResourceLoadScheduler.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h" #include "platform/loader/fetch/ResourceLoaderOptions.h"
#include "platform/loader/fetch/SubstituteData.h" #include "platform/loader/fetch/SubstituteData.h"
#include "platform/wtf/HashMap.h" #include "platform/wtf/HashMap.h"
...@@ -152,6 +151,7 @@ class PLATFORM_EXPORT ResourceFetcher ...@@ -152,6 +151,7 @@ class PLATFORM_EXPORT ResourceFetcher
void RemovePreload(Resource*); void RemovePreload(Resource*);
void LoosenLoadThrottlingPolicy() { scheduler_->LoosenThrottlingPolicy(); }
void OnNetworkQuiet() { scheduler_->OnNetworkQuiet(); } void OnNetworkQuiet() { scheduler_->OnNetworkQuiet(); }
// Workaround for https://crbug.com/666214. // Workaround for https://crbug.com/666214.
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
#include "base/metrics/field_trial_params.h" #include "base/metrics/field_trial_params.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "platform/Histogram.h" #include "platform/Histogram.h"
#include "platform/loader/fetch/FetchContext.h"
#include "platform/runtime_enabled_features.h" #include "platform/runtime_enabled_features.h"
#include "public/platform/Platform.h"
namespace blink { namespace blink {
...@@ -330,11 +332,19 @@ ResourceLoadScheduler::ResourceLoadScheduler(FetchContext* context) ...@@ -330,11 +332,19 @@ ResourceLoadScheduler::ResourceLoadScheduler(FetchContext* context)
if (!scheduler) if (!scheduler)
return; return;
if (Platform::Current()->IsRendererSideResourceSchedulerEnabled())
policy_ = context->InitialLoadThrottlingPolicy();
is_enabled_ = true; is_enabled_ = true;
scheduler->AddThrottlingObserver(WebFrameScheduler::ObserverType::kLoader, scheduler->AddThrottlingObserver(WebFrameScheduler::ObserverType::kLoader,
this); this);
} }
ResourceLoadScheduler* ResourceLoadScheduler::Create(FetchContext* context) {
return new ResourceLoadScheduler(context ? context
: &FetchContext::NullInstance());
}
ResourceLoadScheduler::~ResourceLoadScheduler() = default; ResourceLoadScheduler::~ResourceLoadScheduler() = default;
void ResourceLoadScheduler::Trace(blink::Visitor* visitor) { void ResourceLoadScheduler::Trace(blink::Visitor* visitor) {
...@@ -342,6 +352,17 @@ void ResourceLoadScheduler::Trace(blink::Visitor* visitor) { ...@@ -342,6 +352,17 @@ void ResourceLoadScheduler::Trace(blink::Visitor* visitor) {
visitor->Trace(context_); visitor->Trace(context_);
} }
void ResourceLoadScheduler::LoosenThrottlingPolicy() {
switch (policy_) {
case ThrottlingPolicy::kTight:
break;
case ThrottlingPolicy::kNormal:
return;
}
policy_ = ThrottlingPolicy::kNormal;
MaybeRun();
}
void ResourceLoadScheduler::Shutdown() { void ResourceLoadScheduler::Shutdown() {
// Do nothing if the feature is not enabled, or Shutdown() was already called. // Do nothing if the feature is not enabled, or Shutdown() was already called.
if (is_shutdown_) if (is_shutdown_)
...@@ -405,12 +426,6 @@ void ResourceLoadScheduler::SetPriority(ClientId client_id, ...@@ -405,12 +426,6 @@ void ResourceLoadScheduler::SetPriority(ClientId client_id,
client_it->value->priority = priority; client_it->value->priority = priority;
client_it->value->intra_priority = intra_priority; client_it->value->intra_priority = intra_priority;
if (!IsThrottablePriority(priority)) {
ResourceLoadSchedulerClient* client = client_it->value->client;
pending_request_map_.erase(client_it);
Run(client_id, client);
return;
}
pending_requests_.emplace(client_id, priority, intra_priority); pending_requests_.emplace(client_id, priority, intra_priority);
MaybeRun(); MaybeRun();
} }
...@@ -447,8 +462,11 @@ bool ResourceLoadScheduler::Release( ...@@ -447,8 +462,11 @@ bool ResourceLoadScheduler::Release(
return false; return false;
} }
void ResourceLoadScheduler::SetOutstandingLimitForTesting(size_t limit) { void ResourceLoadScheduler::SetOutstandingLimitForTesting(size_t tight_limit,
SetOutstandingLimitAndMaybeRun(limit); size_t limit) {
tight_outstanding_limit_ = tight_limit;
outstanding_limit_ = limit;
MaybeRun();
} }
void ResourceLoadScheduler::OnNetworkQuiet() { void ResourceLoadScheduler::OnNetworkQuiet() {
...@@ -525,7 +543,14 @@ bool ResourceLoadScheduler::IsThrottablePriority( ...@@ -525,7 +543,14 @@ bool ResourceLoadScheduler::IsThrottablePriority(
} }
} }
return priority < ResourceLoadPriority::kMedium; switch (policy_) {
case ThrottlingPolicy::kTight:
return priority < ResourceLoadPriority::kHigh;
case ThrottlingPolicy::kNormal:
return priority < ResourceLoadPriority::kMedium;
}
NOTREACHED();
return true;
} }
void ResourceLoadScheduler::OnThrottlingStateChanged( void ResourceLoadScheduler::OnThrottlingStateChanged(
...@@ -570,8 +595,23 @@ void ResourceLoadScheduler::MaybeRun() { ...@@ -570,8 +595,23 @@ void ResourceLoadScheduler::MaybeRun() {
return; return;
while (!pending_requests_.empty()) { while (!pending_requests_.empty()) {
if (running_requests_.size() >= outstanding_limit_) bool has_enough_running_requets = false;
return;
switch (policy_) {
case ThrottlingPolicy::kTight:
if (running_requests_.size() >= tight_outstanding_limit_)
has_enough_running_requets = true;
break;
case ThrottlingPolicy::kNormal:
if (running_requests_.size() >= outstanding_limit_)
has_enough_running_requets = true;
break;
}
if (IsThrottablePriority(pending_requests_.begin()->priority) &&
has_enough_running_requets) {
break;
}
ClientId id = pending_requests_.begin()->client_id; ClientId id = pending_requests_.begin()->client_id;
pending_requests_.erase(pending_requests_.begin()); pending_requests_.erase(pending_requests_.begin());
auto found = pending_request_map_.find(id); auto found = pending_request_map_.find(id);
......
...@@ -9,13 +9,14 @@ ...@@ -9,13 +9,14 @@
#include "platform/WebFrameScheduler.h" #include "platform/WebFrameScheduler.h"
#include "platform/heap/GarbageCollected.h" #include "platform/heap/GarbageCollected.h"
#include "platform/heap/HeapAllocator.h" #include "platform/heap/HeapAllocator.h"
#include "platform/loader/fetch/FetchContext.h"
#include "platform/loader/fetch/Resource.h" #include "platform/loader/fetch/Resource.h"
#include "platform/loader/fetch/ResourceLoaderOptions.h" #include "platform/loader/fetch/ResourceLoaderOptions.h"
#include "platform/wtf/HashSet.h" #include "platform/wtf/HashSet.h"
namespace blink { namespace blink {
class FetchContext;
// Client interface to use the throttling/scheduling functionality that // Client interface to use the throttling/scheduling functionality that
// ResourceLoadScheduler provides. // ResourceLoadScheduler provides.
class PLATFORM_EXPORT ResourceLoadSchedulerClient class PLATFORM_EXPORT ResourceLoadSchedulerClient
...@@ -34,6 +35,9 @@ class PLATFORM_EXPORT ResourceLoadSchedulerClient ...@@ -34,6 +35,9 @@ class PLATFORM_EXPORT ResourceLoadSchedulerClient
// in-flight requests that are granted but are not released (by Release()) yet. // in-flight requests that are granted but are not released (by Release()) yet.
// Note: If FetchContext can not provide a WebFrameScheduler, throttling and // Note: If FetchContext can not provide a WebFrameScheduler, throttling and
// scheduling functionalities will be completely disabled. // scheduling functionalities will be completely disabled.
//
// TODO(yhirano): Provide the general algorithm and running experiments
// information.
class PLATFORM_EXPORT ResourceLoadScheduler final class PLATFORM_EXPORT ResourceLoadScheduler final
: public GarbageCollectedFinalized<ResourceLoadScheduler>, : public GarbageCollectedFinalized<ResourceLoadScheduler>,
public WebFrameScheduler::Observer { public WebFrameScheduler::Observer {
...@@ -85,6 +89,12 @@ class PLATFORM_EXPORT ResourceLoadScheduler final ...@@ -85,6 +89,12 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
int64_t decoded_body_length_ = 0; int64_t decoded_body_length_ = 0;
}; };
// ResourceLoadScheduler has two policies: |kTight| and |kNormal|. Currently
// this is used to support aggressive throttling while the corresponding frame
// is in layout-blocking phase. There is only one state transition,
// |kTight| => |kNormal|, which is done by |LoosenThrottlingPolicy|.
enum class ThrottlingPolicy { kTight, kNormal };
// Returned on Request(). Caller should need to return it via Release(). // Returned on Request(). Caller should need to return it via Release().
using ClientId = uint64_t; using ClientId = uint64_t;
...@@ -93,13 +103,16 @@ class PLATFORM_EXPORT ResourceLoadScheduler final ...@@ -93,13 +103,16 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
static constexpr size_t kOutstandingUnlimited = static constexpr size_t kOutstandingUnlimited =
std::numeric_limits<size_t>::max(); std::numeric_limits<size_t>::max();
static ResourceLoadScheduler* Create(FetchContext* context = nullptr) { static ResourceLoadScheduler* Create(FetchContext* = nullptr);
return new ResourceLoadScheduler(context ? context
: &FetchContext::NullInstance());
}
~ResourceLoadScheduler(); ~ResourceLoadScheduler();
void Trace(blink::Visitor*); void Trace(blink::Visitor*);
// Changes the policy from |kTight| to |kNormal|. This function can be called
// multiple times, and does nothing when the scheduler is already working with
// the normal policy. This function may initiate a new resource loading.
void LoosenThrottlingPolicy();
// Stops all operations including observing throttling signals. // Stops all operations including observing throttling signals.
// ResourceLoadSchedulerClient::Run() will not be called once this method is // ResourceLoadSchedulerClient::Run() will not be called once this method is
// called. This method can be called multiple times safely. // called. This method can be called multiple times safely.
...@@ -127,7 +140,10 @@ class PLATFORM_EXPORT ResourceLoadScheduler final ...@@ -127,7 +140,10 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
bool Release(ClientId, ReleaseOption, const TrafficReportHints&); bool Release(ClientId, ReleaseOption, const TrafficReportHints&);
// Sets outstanding limit for testing. // Sets outstanding limit for testing.
void SetOutstandingLimitForTesting(size_t limit); void SetOutstandingLimitForTesting(size_t limit) {
SetOutstandingLimitForTesting(limit, limit);
}
void SetOutstandingLimitForTesting(size_t tight_limit, size_t limit);
void OnNetworkQuiet(); void OnNetworkQuiet();
...@@ -200,9 +216,14 @@ class PLATFORM_EXPORT ResourceLoadScheduler final ...@@ -200,9 +216,14 @@ class PLATFORM_EXPORT ResourceLoadScheduler final
// Can be modified by field trial flags or for testing. // Can be modified by field trial flags or for testing.
bool is_enabled_ = false; bool is_enabled_ = false;
// Outstanding limit. 0u means unlimited. ThrottlingPolicy policy_ = ThrottlingPolicy::kNormal;
// Used to limit outstanding requests when |policy_| is kTight.
size_t tight_outstanding_limit_ = kOutstandingUnlimited;
// TODO(crbug.com/735410): If this throttling is enabled always, it makes some // TODO(crbug.com/735410): If this throttling is enabled always, it makes some
// tests fail. // tests fail.
// Used to limit outstanding requests when |policy_| is kNormal.
size_t outstanding_limit_ = kOutstandingUnlimited; size_t outstanding_limit_ = kOutstandingUnlimited;
// Outstanding limit for throttled frames. Managed via the field trial. // Outstanding limit for throttled frames. Managed via the field trial.
......
...@@ -286,21 +286,21 @@ TEST_F(ResourceLoadSchedulerTest, PriotrityIsNotConsidered) { ...@@ -286,21 +286,21 @@ TEST_F(ResourceLoadSchedulerTest, PriotrityIsNotConsidered) {
ResourceLoadScheduler::ClientId id1 = ResourceLoadScheduler::kInvalidClientId; ResourceLoadScheduler::ClientId id1 = ResourceLoadScheduler::kInvalidClientId;
scheduler()->Request(client1, ThrottleOption::kCanBeThrottled, scheduler()->Request(client1, ThrottleOption::kCanBeThrottled,
ResourceLoadPriority::kLow, 0 /* intra_priority */, ResourceLoadPriority::kLowest, 10 /* intra_priority */,
&id1); &id1);
EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id1); EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id1);
MockClient* client2 = new MockClient; MockClient* client2 = new MockClient;
ResourceLoadScheduler::ClientId id2 = ResourceLoadScheduler::kInvalidClientId; ResourceLoadScheduler::ClientId id2 = ResourceLoadScheduler::kInvalidClientId;
scheduler()->Request(client2, ThrottleOption::kCanBeThrottled, scheduler()->Request(client2, ThrottleOption::kCanBeThrottled,
ResourceLoadPriority::kMedium, 0 /* intra_priority */, ResourceLoadPriority::kLow, 1 /* intra_priority */,
&id2); &id2);
EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id2); EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id2);
MockClient* client3 = new MockClient; MockClient* client3 = new MockClient;
ResourceLoadScheduler::ClientId id3 = ResourceLoadScheduler::kInvalidClientId; ResourceLoadScheduler::ClientId id3 = ResourceLoadScheduler::kInvalidClientId;
scheduler()->Request(client3, ThrottleOption::kCanBeThrottled, scheduler()->Request(client3, ThrottleOption::kCanBeThrottled,
ResourceLoadPriority::kHigh, 0 /* intra_priority */, ResourceLoadPriority::kLow, 3 /* intra_priority */,
&id3); &id3);
EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id3); EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id3);
...@@ -400,6 +400,16 @@ TEST_F(RendererSideResourceSchedulerTest, PriotrityIsConsidered) { ...@@ -400,6 +400,16 @@ TEST_F(RendererSideResourceSchedulerTest, PriotrityIsConsidered) {
} }
TEST_F(RendererSideResourceSchedulerTest, IsThrottablePriority) { TEST_F(RendererSideResourceSchedulerTest, IsThrottablePriority) {
EXPECT_TRUE(
scheduler()->IsThrottablePriority(ResourceLoadPriority::kVeryLow));
EXPECT_TRUE(scheduler()->IsThrottablePriority(ResourceLoadPriority::kLow));
EXPECT_TRUE(scheduler()->IsThrottablePriority(ResourceLoadPriority::kMedium));
EXPECT_FALSE(scheduler()->IsThrottablePriority(ResourceLoadPriority::kHigh));
EXPECT_FALSE(
scheduler()->IsThrottablePriority(ResourceLoadPriority::kVeryHigh));
scheduler()->LoosenThrottlingPolicy();
EXPECT_TRUE( EXPECT_TRUE(
scheduler()->IsThrottablePriority(ResourceLoadPriority::kVeryLow)); scheduler()->IsThrottablePriority(ResourceLoadPriority::kVeryLow));
EXPECT_TRUE(scheduler()->IsThrottablePriority(ResourceLoadPriority::kLow)); EXPECT_TRUE(scheduler()->IsThrottablePriority(ResourceLoadPriority::kLow));
...@@ -411,6 +421,8 @@ TEST_F(RendererSideResourceSchedulerTest, IsThrottablePriority) { ...@@ -411,6 +421,8 @@ TEST_F(RendererSideResourceSchedulerTest, IsThrottablePriority) {
} }
TEST_F(RendererSideResourceSchedulerTest, SetPriority) { TEST_F(RendererSideResourceSchedulerTest, SetPriority) {
// Start with the normal scheduling policy.
scheduler()->LoosenThrottlingPolicy();
// Push three requests. // Push three requests.
MockClient* client1 = new MockClient; MockClient* client1 = new MockClient;
...@@ -470,5 +482,90 @@ TEST_F(RendererSideResourceSchedulerTest, SetPriority) { ...@@ -470,5 +482,90 @@ TEST_F(RendererSideResourceSchedulerTest, SetPriority) {
ResourceLoadScheduler::TrafficReportHints::InvalidInstance())); ResourceLoadScheduler::TrafficReportHints::InvalidInstance()));
} }
TEST_F(RendererSideResourceSchedulerTest, LoosenThrottlingPolicy) {
MockClient* client1 = new MockClient;
scheduler()->SetOutstandingLimitForTesting(0, 0);
ResourceLoadScheduler::ClientId id1 = ResourceLoadScheduler::kInvalidClientId;
scheduler()->Request(client1, ThrottleOption::kCanBeThrottled,
ResourceLoadPriority::kLowest, 0 /* intra_priority */,
&id1);
EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id1);
MockClient* client2 = new MockClient;
ResourceLoadScheduler::ClientId id2 = ResourceLoadScheduler::kInvalidClientId;
scheduler()->Request(client2, ThrottleOption::kCanBeThrottled,
ResourceLoadPriority::kLowest, 0 /* intra_priority */,
&id2);
EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id2);
MockClient* client3 = new MockClient;
ResourceLoadScheduler::ClientId id3 = ResourceLoadScheduler::kInvalidClientId;
scheduler()->Request(client3, ThrottleOption::kCanBeThrottled,
ResourceLoadPriority::kLowest, 0 /* intra_priority */,
&id3);
EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id3);
MockClient* client4 = new MockClient;
ResourceLoadScheduler::ClientId id4 = ResourceLoadScheduler::kInvalidClientId;
scheduler()->Request(client4, ThrottleOption::kCanBeThrottled,
ResourceLoadPriority::kLowest, 0 /* intra_priority */,
&id4);
EXPECT_NE(ResourceLoadScheduler::kInvalidClientId, id4);
scheduler()->SetPriority(id2, ResourceLoadPriority::kLow, 0);
scheduler()->SetPriority(id3, ResourceLoadPriority::kLow, 0);
scheduler()->SetPriority(id4, ResourceLoadPriority::kMedium, 0);
// As the policy is |kTight|, |kMedium| is throttled.
EXPECT_FALSE(client1->WasRan());
EXPECT_FALSE(client2->WasRan());
EXPECT_FALSE(client3->WasRan());
EXPECT_FALSE(client4->WasRan());
scheduler()->SetOutstandingLimitForTesting(0, 2);
// MockFetchContext's initial scheduling policy is |kTight|, setting the
// outstanding limit for the normal mode doesn't take effect.
EXPECT_FALSE(client1->WasRan());
EXPECT_FALSE(client2->WasRan());
EXPECT_FALSE(client3->WasRan());
EXPECT_FALSE(client4->WasRan());
// Now let's tighten the limit again.
scheduler()->SetOutstandingLimitForTesting(0, 0);
// ...and change the scheduling policy to |kNormal|, where priority >=
// |kMedium| requests are not throttled.
scheduler()->LoosenThrottlingPolicy();
EXPECT_FALSE(client1->WasRan());
EXPECT_FALSE(client2->WasRan());
EXPECT_FALSE(client3->WasRan());
EXPECT_TRUE(client4->WasRan());
scheduler()->SetOutstandingLimitForTesting(0, 2);
EXPECT_FALSE(client1->WasRan());
EXPECT_TRUE(client2->WasRan());
EXPECT_FALSE(client3->WasRan());
EXPECT_TRUE(client4->WasRan());
// Release all.
EXPECT_TRUE(scheduler()->Release(
id3, ResourceLoadScheduler::ReleaseOption::kReleaseOnly,
ResourceLoadScheduler::TrafficReportHints::InvalidInstance()));
EXPECT_TRUE(scheduler()->Release(
id4, ResourceLoadScheduler::ReleaseOption::kReleaseOnly,
ResourceLoadScheduler::TrafficReportHints::InvalidInstance()));
EXPECT_TRUE(scheduler()->Release(
id2, ResourceLoadScheduler::ReleaseOption::kReleaseOnly,
ResourceLoadScheduler::TrafficReportHints::InvalidInstance()));
EXPECT_TRUE(scheduler()->Release(
id1, ResourceLoadScheduler::ReleaseOption::kReleaseOnly,
ResourceLoadScheduler::TrafficReportHints::InvalidInstance()));
}
} // namespace } // namespace
} // namespace blink } // namespace blink
...@@ -96,6 +96,11 @@ class MockFetchContext : public FetchContext { ...@@ -96,6 +96,11 @@ class MockFetchContext : public FetchContext {
return url_loader_factory_->CreateURLLoader(wrapped, task_runner); return url_loader_factory_->CreateURLLoader(wrapped, task_runner);
} }
ResourceLoadScheduler::ThrottlingPolicy InitialLoadThrottlingPolicy()
const override {
return ResourceLoadScheduler::ThrottlingPolicy::kTight;
}
WebFrameScheduler* GetFrameScheduler() override { WebFrameScheduler* GetFrameScheduler() override {
return frame_scheduler_.get(); return frame_scheduler_.get();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment