chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOAD_SCHEDULER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOAD_SCHEDULER_H_

#include <map>
#include <set>

#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "base/types/strong_alias.h"
#include "net/http/http_connection_info.h"
#include "third_party/blink/renderer/platform/allow_discouraged_type.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"

namespace base {
class Clock;
}

namespace blink {

class DetachableConsoleLogger;
class DetachableResourceFetcherProperties;
class LoadingBehaviorObserver;

// Client interface to use the throttling/scheduling functionality that
// ResourceLoadScheduler provides.
class PLATFORM_EXPORT ResourceLoadSchedulerClient
    : public GarbageCollectedMixin {};

// ResourceLoadScheduler provides a unified per-frame infrastructure to schedule
// loading requests. When Request() is called with a
// ResourceLoadSchedulerClient |client|, it calls |client|'s Run() method
// synchronously or asynchronously to notify that |client| can start loading.
//
// A ResourceLoadScheduler may initiate a new resource loading in the following
// cases:
// - When Request() is called
// - When LoosenThrottlingPolicy() is called
// - When SetPriority() is called
// - When Release() is called with kReleaseAndSchedule
// - When OnThrottlingStateChanged() is called
//
// A ResourceLoadScheduler determines if a request can be throttleable or not,
// and keeps track of pending throttleable requests with priority information
// (i.e., ResourceLoadPriority accompanied with an integer called
// "intra-priority"). Here are the general principles:
//  - A ResourceLoadScheduler does not throttle requests that cannot be
//    throttleable. It will call client's Run() method as soon as possible.
//  - A ResourceLoadScheduler determines whether a request can be throttleable
//    by seeing Request()'s ThrottleOption argument and requests' priority
//    information. Requests' priority information can be modified via
//    SetPriority().
//  - A ResourceLoadScheulder won't initiate a new resource loading which can
//    be throttleable when there are more active throttleable requests loading
//    activities more than its internal threshold (i.e., what
//    GetOutstandingLimit() returns)".
//  - Resource loading requests are not throttled when the frame is in the
//    foreground tab.
//  - Resource loading requests are throttled when the frame is in a
//    background tab. It has different thresholds for the main frame
//    and sub frames. When the frame has been background for more than five
//    minutes, all throttleable resource loading requests are throttled
//    indefinitely (i.e., threshold is zero in such a circumstance).
//
//  ResourceLoadScheduler has two modes each of which has its own threshold.
//   - Tight mode (used until the frame sees a <body> element):
//     ResourceLoadScheduler considers a request throttleable if its priority
//     is less than |kHigh|.
//   - Normal mode:
//     ResourceLoadScheduler considers a request throttleable if its priority
//     is less than |kMedium|.
//
// Here is an running experiment:
//   - (As of M86): Low-priority requests are delayed behind "important"
//     requests before some general loading milestone has been reached.
//     "Important", for the experiment means either kHigh or kMedium priority,
//     and the milestones being experimented with are first paint and first
//     contentful paint so far.
//
// Here is a planned experiment (not started yet):
//   - network::VisibilityAwareResourceScheduler
//     An experimental feature with the goal of integrating
//     blink::ResourceLoadScheduler into network::ResourceScheduler for better
//     resource scheduling across multiple frames.
//     TODO(https://crbug.com/1457817): Disable or relax throttling/stopping
//     requests in this class once network::ResoureceScheduler implements
//     similar capabilities.
class PLATFORM_EXPORT ResourceLoadScheduler final
    : public GarbageCollected<ResourceLoadScheduler> {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOAD_SCHEDULER_H_