Remove WriteScheduler interface.
It only has one implementations and there are no plans to add any more.
PiperOrigin-RevId: 499875408
diff --git a/build/source_list.bzl b/build/source_list.bzl
index f43b662..1a6277f 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -75,7 +75,6 @@
"http2/adapter/window_manager.h",
"http2/core/http2_trace_logging.h",
"http2/core/priority_write_scheduler.h",
- "http2/core/write_scheduler.h",
"http2/decoder/decode_buffer.h",
"http2/decoder/decode_http2_structures.h",
"http2/decoder/decode_status.h",
diff --git a/build/source_list.gni b/build/source_list.gni
index 60ff738..99ebb16 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -75,7 +75,6 @@
"src/quiche/http2/adapter/window_manager.h",
"src/quiche/http2/core/http2_trace_logging.h",
"src/quiche/http2/core/priority_write_scheduler.h",
- "src/quiche/http2/core/write_scheduler.h",
"src/quiche/http2/decoder/decode_buffer.h",
"src/quiche/http2/decoder/decode_http2_structures.h",
"src/quiche/http2/decoder/decode_status.h",
diff --git a/build/source_list.json b/build/source_list.json
index c8683c8..10b5cd5 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -74,7 +74,6 @@
"quiche/http2/adapter/window_manager.h",
"quiche/http2/core/http2_trace_logging.h",
"quiche/http2/core/priority_write_scheduler.h",
- "quiche/http2/core/write_scheduler.h",
"quiche/http2/decoder/decode_buffer.h",
"quiche/http2/decoder/decode_http2_structures.h",
"quiche/http2/decoder/decode_status.h",
diff --git a/quiche/http2/core/priority_write_scheduler.h b/quiche/http2/core/priority_write_scheduler.h
index 6f7b92f..1c3820d 100644
--- a/quiche/http2/core/priority_write_scheduler.h
+++ b/quiche/http2/core/priority_write_scheduler.h
@@ -16,7 +16,6 @@
#include "absl/container/flat_hash_map.h"
#include "absl/strings/str_cat.h"
-#include "quiche/http2/core/write_scheduler.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"
@@ -30,23 +29,32 @@
class PriorityWriteSchedulerPeer;
}
-// WriteScheduler implementation that manages the order in which streams are
-// written using the SPDY priority scheme described at:
-// https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority
+// PriorityWriteScheduler manages the order in which HTTP/2 or HTTP/3 streams
+// are written. Each stream has a priority, which is an integer between 0 and 7.
+// Higher priority (lower integer value) streams are always given precedence
+// over lower priority (higher value) streams, as long as the higher priority
+// stream is not blocked.
//
-// Internally, PriorityWriteScheduler consists of 8 PriorityInfo objects, one
-// for each priority value. Each PriorityInfo contains a list of streams of
-// that priority that are ready to write, as well as a timestamp of the last
-// I/O event that occurred for a stream of that priority.
+// Each stream can be in one of two states: ready or not ready (for writing).
+// Ready state is changed by calling the MarkStreamReady() and
+// MarkStreamNotReady() methods. Only streams in the ready state can be returned
+// by PopNextReadyStream(). When returned by that method, the stream's state
+// changes to not ready.
//
template <typename StreamIdType>
-class QUICHE_EXPORT PriorityWriteScheduler
- : public WriteScheduler<StreamIdType> {
+class QUICHE_EXPORT PriorityWriteScheduler {
public:
- using typename WriteScheduler<StreamIdType>::StreamPrecedenceType;
+ using StreamPrecedenceType = spdy::StreamPrecedence<StreamIdType>;
+ // Registers new stream `stream_id` with the scheduler, assigning it the
+ // given precedence. If the scheduler supports stream dependencies, the
+ // stream is inserted into the dependency tree under
+ // `precedence.parent_id()`.
+ //
+ // Preconditions: `stream_id` should be unregistered, and
+ // `precedence.parent_id()` should be registered or `kHttp2RootStreamId`.
void RegisterStream(StreamIdType stream_id,
- const StreamPrecedenceType& precedence) override {
+ const StreamPrecedenceType& precedence) {
auto stream_info = std::make_unique<StreamInfo>(
StreamInfo{precedence.spdy3_priority(), stream_id, false});
bool inserted =
@@ -56,7 +64,11 @@
<< "Stream " << stream_id << " already registered";
}
- void UnregisterStream(StreamIdType stream_id) override {
+ // Unregisters the given stream from the scheduler, which will no longer keep
+ // state for it.
+ //
+ // Preconditions: `stream_id` should be registered.
+ void UnregisterStream(StreamIdType stream_id) {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_BUG(spdy_bug_19_3) << "Stream " << stream_id << " not registered";
@@ -71,12 +83,18 @@
stream_infos_.erase(it);
}
- bool StreamRegistered(StreamIdType stream_id) const override {
+ // Returns true if the given stream is currently registered.
+ bool StreamRegistered(StreamIdType stream_id) const {
return stream_infos_.find(stream_id) != stream_infos_.end();
}
- StreamPrecedenceType GetStreamPrecedence(
- StreamIdType stream_id) const override {
+ // Returns the precedence of the specified stream. If the scheduler supports
+ // stream dependencies, calling `parent_id()` on the return value returns the
+ // stream's parent, and calling `exclusive()` returns true iff the specified
+ // stream is an only child of the parent stream.
+ //
+ // Preconditions: `stream_id` should be registered.
+ StreamPrecedenceType GetStreamPrecedence(StreamIdType stream_id) const {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_DVLOG(1) << "Stream " << stream_id << " not registered";
@@ -85,8 +103,14 @@
return StreamPrecedenceType(it->second->priority);
}
+ // Updates the precedence of the given stream. If the scheduler supports
+ // stream dependencies, `stream_id`'s parent will be updated to be
+ // `precedence.parent_id()` if it is not already.
+ //
+ // Preconditions: `stream_id` should be unregistered, and
+ // `precedence.parent_id()` should be registered or `kHttp2RootStreamId`.
void UpdateStreamPrecedence(StreamIdType stream_id,
- const StreamPrecedenceType& precedence) override {
+ const StreamPrecedenceType& precedence) {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
// TODO(mpw): add to stream_infos_ on demand--see b/15676312.
@@ -108,13 +132,20 @@
stream_info->priority = new_priority;
}
+ // Returns child streams of the given stream, if any. If the scheduler
+ // doesn't support stream dependencies, returns an empty vector.
+ //
+ // Preconditions: `stream_id` should be registered.
std::vector<StreamIdType> GetStreamChildren(
- StreamIdType /*stream_id*/) const override {
+ StreamIdType /*stream_id*/) const {
return std::vector<StreamIdType>();
}
- void RecordStreamEventTime(StreamIdType stream_id,
- int64_t now_in_usec) override {
+ // Records time (in microseconds) of a read/write event for the given
+ // stream.
+ //
+ // Preconditions: `stream_id` should be registered.
+ void RecordStreamEventTime(StreamIdType stream_id, int64_t now_in_usec) {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_BUG(spdy_bug_19_4) << "Stream " << stream_id << " not registered";
@@ -125,7 +156,12 @@
std::max(priority_info.last_event_time_usec, now_in_usec);
}
- int64_t GetLatestEventWithPrecedence(StreamIdType stream_id) const override {
+ // Returns time (in microseconds) of the last read/write event for a stream
+ // with higher priority than the priority of the given stream, or 0 if there
+ // is no such event.
+ //
+ // Preconditions: `stream_id` should be registered.
+ int64_t GetLatestEventWithPrecedence(StreamIdType stream_id) const {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_BUG(spdy_bug_19_5) << "Stream " << stream_id << " not registered";
@@ -141,13 +177,22 @@
return last_event_time_usec;
}
- StreamIdType PopNextReadyStream() override {
+ // If the scheduler has any ready streams, returns the next scheduled
+ // ready stream, in the process transitioning the stream from ready to not
+ // ready.
+ //
+ // Preconditions: `HasReadyStreams() == true`
+ StreamIdType PopNextReadyStream() {
return std::get<0>(PopNextReadyStreamAndPrecedence());
}
- // Returns the next ready stream and its precedence.
+ // If the scheduler has any ready streams, returns the next scheduled
+ // ready stream and its priority, in the process transitioning the stream from
+ // ready to not ready.
+ //
+ // Preconditions: `HasReadyStreams() == true`
std::tuple<StreamIdType, StreamPrecedenceType>
- PopNextReadyStreamAndPrecedence() override {
+ PopNextReadyStreamAndPrecedence() {
for (spdy::SpdyPriority p = spdy::kV3HighestPriority;
p <= spdy::kV3LowestPriority; ++p) {
ReadyList& ready_list = priority_infos_[p].ready_list;
@@ -167,7 +212,12 @@
return std::make_tuple(0, StreamPrecedenceType(spdy::kV3LowestPriority));
}
- bool ShouldYield(StreamIdType stream_id) const override {
+ // Returns true if there's another stream ahead of the given stream in the
+ // scheduling queue. This function can be called to see if the given stream
+ // should yield work to another stream.
+ //
+ // Preconditions: `stream_id` should be registered.
+ bool ShouldYield(StreamIdType stream_id) const {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_BUG(spdy_bug_19_7) << "Stream " << stream_id << " not registered";
@@ -195,7 +245,12 @@
return true;
}
- void MarkStreamReady(StreamIdType stream_id, bool add_to_front) override {
+ // Marks the stream as ready to write. If the stream was already ready, does
+ // nothing. If add_to_front is true, the stream is scheduled ahead of other
+ // streams of the same priority/weight, otherwise it is scheduled behind them.
+ //
+ // Preconditions: `stream_id` should be registered.
+ void MarkStreamReady(StreamIdType stream_id, bool add_to_front) {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_BUG(spdy_bug_19_8) << "Stream " << stream_id << " not registered";
@@ -215,7 +270,11 @@
stream_info->ready = true;
}
- void MarkStreamNotReady(StreamIdType stream_id) override {
+ // Marks the stream as not ready to write. If the stream is not registered or
+ // not ready, does nothing.
+ //
+ // Preconditions: `stream_id` should be registered.
+ void MarkStreamNotReady(StreamIdType stream_id) {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_BUG(spdy_bug_19_9) << "Stream " << stream_id << " not registered";
@@ -231,22 +290,24 @@
stream_info->ready = false;
}
- // Returns true iff the number of ready streams is non-zero.
- bool HasReadyStreams() const override { return num_ready_streams_ > 0; }
+ // Returns true iff the scheduler has any ready streams.
+ bool HasReadyStreams() const { return num_ready_streams_ > 0; }
- // Returns the number of ready streams.
- size_t NumReadyStreams() const override { return num_ready_streams_; }
+ // Returns the number of streams currently marked ready.
+ size_t NumReadyStreams() const { return num_ready_streams_; }
- size_t NumRegisteredStreams() const override { return stream_infos_.size(); }
+ // Returns the number of registered streams.
+ size_t NumRegisteredStreams() const { return stream_infos_.size(); }
- std::string DebugString() const override {
+ // Returns summary of internal state, for logging/debugging.
+ std::string DebugString() const {
return absl::StrCat(
"PriorityWriteScheduler {num_streams=", stream_infos_.size(),
" num_ready_streams=", NumReadyStreams(), "}");
}
- // Returns true if a stream is ready.
- bool IsStreamReady(StreamIdType stream_id) const override {
+ // Returns true if stream with `stream_id` is ready.
+ bool IsStreamReady(StreamIdType stream_id) const {
auto it = stream_infos_.find(stream_id);
if (it == stream_infos_.end()) {
QUICHE_DLOG(INFO) << "Stream " << stream_id << " not registered";
diff --git a/quiche/http2/core/write_scheduler.h b/quiche/http2/core/write_scheduler.h
deleted file mode 100644
index ce0ddc1..0000000
--- a/quiche/http2/core/write_scheduler.h
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2016 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.
-
-#ifndef QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
-#define QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_
-
-#include <cstdint>
-#include <string>
-#include <tuple>
-#include <vector>
-
-#include "quiche/common/platform/api/quiche_export.h"
-#include "quiche/spdy/core/spdy_protocol.h"
-
-namespace http2 {
-
-// Abstract superclass for classes that decide which SPDY or HTTP/2 stream to
-// write next. Concrete subclasses implement various scheduling policies:
-//
-// PriorityWriteScheduler: implements SPDY priority-based stream scheduling,
-// where (writable) higher-priority streams are always given precedence
-// over lower-priority streams.
-//
-// The type used to represent stream IDs (StreamIdType) is templated in order
-// to allow for use by both SPDY and QUIC codebases. It must be a POD that
-// supports comparison (i.e., a numeric type).
-//
-// Each stream can be in one of two states: ready or not ready (for writing).
-// Ready state is changed by calling the MarkStreamReady() and
-// MarkStreamNotReady() methods. Only streams in the ready state can be
-// returned by PopNextReadyStream(); when returned by that method, the stream's
-// state changes to not ready.
-template <typename StreamIdType>
-class QUICHE_EXPORT WriteScheduler {
- public:
- typedef spdy::StreamPrecedence<StreamIdType> StreamPrecedenceType;
-
- virtual ~WriteScheduler() {}
-
- // Registers new stream |stream_id| with the scheduler, assigning it the
- // given precedence. If the scheduler supports stream dependencies, the
- // stream is inserted into the dependency tree under
- // |precedence.parent_id()|.
- //
- // Preconditions: |stream_id| should be unregistered, and
- // |precedence.parent_id()| should be registered or |kHttp2RootStreamId|.
- virtual void RegisterStream(StreamIdType stream_id,
- const StreamPrecedenceType& precedence) = 0;
-
- // Unregisters the given stream from the scheduler, which will no longer keep
- // state for it.
- //
- // Preconditions: |stream_id| should be registered.
- virtual void UnregisterStream(StreamIdType stream_id) = 0;
-
- // Returns true if the given stream is currently registered.
- virtual bool StreamRegistered(StreamIdType stream_id) const = 0;
-
- // Returns the precedence of the specified stream. If the scheduler supports
- // stream dependencies, calling |parent_id()| on the return value returns the
- // stream's parent, and calling |exclusive()| returns true iff the specified
- // stream is an only child of the parent stream.
- //
- // Preconditions: |stream_id| should be registered.
- virtual StreamPrecedenceType GetStreamPrecedence(
- StreamIdType stream_id) const = 0;
-
- // Updates the precedence of the given stream. If the scheduler supports
- // stream dependencies, |stream_id|'s parent will be updated to be
- // |precedence.parent_id()| if it is not already.
- //
- // Preconditions: |stream_id| should be unregistered, and
- // |precedence.parent_id()| should be registered or |kHttp2RootStreamId|.
- virtual void UpdateStreamPrecedence(
- StreamIdType stream_id, const StreamPrecedenceType& precedence) = 0;
-
- // Returns child streams of the given stream, if any. If the scheduler
- // doesn't support stream dependencies, returns an empty vector.
- //
- // Preconditions: |stream_id| should be registered.
- virtual std::vector<StreamIdType> GetStreamChildren(
- StreamIdType stream_id) const = 0;
-
- // Records time (in microseconds) of a read/write event for the given
- // stream.
- //
- // Preconditions: |stream_id| should be registered.
- virtual void RecordStreamEventTime(StreamIdType stream_id,
- int64_t now_in_usec) = 0;
-
- // Returns time (in microseconds) of the last read/write event for a stream
- // with higher priority than the priority of the given stream, or 0 if there
- // is no such event.
- //
- // Preconditions: |stream_id| should be registered.
- virtual int64_t GetLatestEventWithPrecedence(
- StreamIdType stream_id) const = 0;
-
- // If the scheduler has any ready streams, returns the next scheduled
- // ready stream, in the process transitioning the stream from ready to not
- // ready.
- //
- // Preconditions: |HasReadyStreams() == true|
- virtual StreamIdType PopNextReadyStream() = 0;
-
- // If the scheduler has any ready streams, returns the next scheduled
- // ready stream and its priority, in the process transitioning the stream from
- // ready to not ready.
- //
- // Preconditions: |HasReadyStreams() == true|
- virtual std::tuple<StreamIdType, StreamPrecedenceType>
- PopNextReadyStreamAndPrecedence() = 0;
-
- // Returns true if there's another stream ahead of the given stream in the
- // scheduling queue. This function can be called to see if the given stream
- // should yield work to another stream.
- //
- // Preconditions: |stream_id| should be registered.
- virtual bool ShouldYield(StreamIdType stream_id) const = 0;
-
- // Marks the stream as ready to write. If the stream was already ready, does
- // nothing. If add_to_front is true, the stream is scheduled ahead of other
- // streams of the same priority/weight, otherwise it is scheduled behind them.
- //
- // Preconditions: |stream_id| should be registered.
- virtual void MarkStreamReady(StreamIdType stream_id, bool add_to_front) = 0;
-
- // Marks the stream as not ready to write. If the stream is not registered or
- // not ready, does nothing.
- //
- // Preconditions: |stream_id| should be registered.
- virtual void MarkStreamNotReady(StreamIdType stream_id) = 0;
-
- // Returns true iff the scheduler has any ready streams.
- virtual bool HasReadyStreams() const = 0;
-
- // Returns the number of streams currently marked ready.
- virtual size_t NumReadyStreams() const = 0;
-
- // Returns true if stream with |stream_id| is ready.
- virtual bool IsStreamReady(StreamIdType stream_id) const = 0;
-
- // Returns the number of registered streams.
- virtual size_t NumRegisteredStreams() const = 0;
-
- // Returns summary of internal state, for logging/debugging.
- virtual std::string DebugString() const = 0;
-};
-
-} // namespace http2
-
-#endif // QUICHE_HTTP2_CORE_WRITE_SCHEDULER_H_