| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f727efb commit bc7f4ef
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2076,6 +2076,20 @@ added: v23.8.0 | |||
| 2076 | 2076 | ||
| 2077 | 2077 | * Type: {bigint} | |
| 2078 | 2078 | ||
| 2079 | + ### `streamStats.bytesAccumulated` | ||
| 2080 | + | ||
| 2081 | + <!-- YAML | ||
| 2082 | + added: REPLACEME | ||
| 2083 | + --> | ||
| 2084 | + | ||
| 2085 | + * Type: {bigint} | ||
| 2086 | + | ||
| 2087 | + The current number of bytes sitting in the stream's receive accumulation | ||
| 2088 | + buffer, awaiting delivery to the application. A value near zero indicates | ||
| 2089 | + the reader is keeping up with incoming data. A value near the stream's | ||
| 2090 | + flow control window indicates the application is not consuming data fast | ||
| 2091 | + enough. | ||
| 2092 | + | ||
| 2079 | 2093 | ### `streamStats.bytesReceived` | |
| 2080 | 2094 | ||
| 2081 | 2095 | <!-- YAML | |
@@ -2124,6 +2138,20 @@ added: v23.8.0 | |||
| 2124 | 2138 | ||
| 2125 | 2139 | * Type: {bigint} | |
| 2126 | 2140 | ||
| 2141 | + ### `streamStats.maxBytesAccumulated` | ||
| 2142 | + | ||
| 2143 | + <!-- YAML | ||
| 2144 | + added: REPLACEME | ||
| 2145 | + --> | ||
| 2146 | + | ||
| 2147 | + * Type: {bigint} | ||
| 2148 | + | ||
| 2149 | + The peak number of bytes that were accumulated in the stream's receive | ||
| 2150 | + buffer at any point during the stream's lifetime. This value only | ||
| 2151 | + increases monotonically. It is useful for diagnosing whether a stream | ||
| 2152 | + experienced backpressure episodes and whether the accumulation buffer | ||
| 2153 | + sizing is appropriate for the workload. | ||
| 2154 | + | ||
| 2127 | 2155 | ### `streamStats.maxOffset` | |
| 2128 | 2156 | ||
| 2129 | 2157 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -108,6 +108,8 @@ const { | |||
| 108 | 108 | IDX_STATS_STREAM_MAX_OFFSET_ACK, | |
| 109 | 109 | IDX_STATS_STREAM_MAX_OFFSET_RECV, | |
| 110 | 110 | IDX_STATS_STREAM_FINAL_SIZE, | |
| 111 | + IDX_STATS_STREAM_BYTES_ACCUMULATED, | ||
| 112 | + IDX_STATS_STREAM_MAX_BYTES_ACCUMULATED, | ||
| 111 | 113 | IDX_STATS_STREAM_COUNT, | |
| 112 | 114 | } = internalBinding('quic'); | |
| 113 | 115 | ||
@@ -166,6 +168,8 @@ assert(IDX_STATS_STREAM_MAX_OFFSET !== undefined); | |||
| 166 | 168 | assert(IDX_STATS_STREAM_MAX_OFFSET_ACK !== undefined); | |
| 167 | 169 | assert(IDX_STATS_STREAM_MAX_OFFSET_RECV !== undefined); | |
| 168 | 170 | assert(IDX_STATS_STREAM_FINAL_SIZE !== undefined); | |
| 171 | + assert(IDX_STATS_STREAM_BYTES_ACCUMULATED !== undefined); | ||
| 172 | + assert(IDX_STATS_STREAM_MAX_BYTES_ACCUMULATED !== undefined); | ||
| 169 | 173 | assert(IDX_STATS_STREAM_COUNT !== undefined); | |
| 170 | 174 | assert(IDX_STATS_SESSION_COUNT !== undefined); | |
| 171 | 175 | ||
@@ -889,6 +893,18 @@ class QuicStreamStats { | |||
| 889 | 893 | return this.#handle[this.#offset + IDX_STATS_STREAM_FINAL_SIZE]; | |
| 890 | 894 | } | |
| 891 | 895 | ||
| 896 | + /** @type {bigint} Current bytes in the receive accumulation buffer. */ | ||
| 897 | + get bytesAccumulated() { | ||
| 898 | + assertIsQuicStreamStats(this); | ||
| 899 | + return this.#handle[this.#offset + IDX_STATS_STREAM_BYTES_ACCUMULATED]; | ||
| 900 | + } | ||
| 901 | + | ||
| 902 | + /** @type {bigint} Peak bytes accumulated over the stream's lifetime. */ | ||
| 903 | + get maxBytesAccumulated() { | ||
| 904 | + assertIsQuicStreamStats(this); | ||
| 905 | + return this.#handle[this.#offset + IDX_STATS_STREAM_MAX_BYTES_ACCUMULATED]; | ||
| 906 | + } | ||
| 907 | + | ||
| 892 | 908 | toString() { | |
| 893 | 909 | return JSONStringify(this.toJSON()); | |
| 894 | 910 | } | |
@@ -907,6 +923,8 @@ class QuicStreamStats { | |||
| 907 | 923 | maxOffsetAcknowledged, | |
| 908 | 924 | maxOffsetReceived, | |
| 909 | 925 | finalSize, | |
| 926 | + bytesAccumulated, | ||
| 927 | + maxBytesAccumulated, | ||
| 910 | 928 | } = this; | |
| 911 | 929 | return { | |
| 912 | 930 | __proto__: null, | |
@@ -924,6 +942,8 @@ class QuicStreamStats { | |||
| 924 | 942 | maxOffsetAcknowledged: `${maxOffsetAcknowledged}`, | |
| 925 | 943 | maxOffsetReceived: `${maxOffsetReceived}`, | |
| 926 | 944 | finalSize: `${finalSize}`, | |
| 945 | + bytesAccumulated: `${bytesAccumulated}`, | ||
| 946 | + maxBytesAccumulated: `${maxBytesAccumulated}`, | ||
| 927 | 947 | }; | |
| 928 | 948 | } | |
| 929 | 949 | ||
@@ -950,6 +970,8 @@ class QuicStreamStats { | |||
| 950 | 970 | maxOffsetAcknowledged, | |
| 951 | 971 | maxOffsetReceived, | |
| 952 | 972 | finalSize, | |
| 973 | + bytesAccumulated, | ||
| 974 | + maxBytesAccumulated, | ||
| 953 | 975 | } = this; | |
| 954 | 976 | ||
| 955 | 977 | return `QuicStreamStats ${inspect({ | |
@@ -965,6 +987,8 @@ class QuicStreamStats { | |||
| 965 | 987 | maxOffsetAcknowledged, | |
| 966 | 988 | maxOffsetReceived, | |
| 967 | 989 | finalSize, | |
| 990 | + bytesAccumulated, | ||
| 991 | + maxBytesAccumulated, | ||
| 968 | 992 | }, opts)}`; | |
| 969 | 993 | } | |
| 970 | 994 | ||
@@ -990,7 +1014,7 @@ class QuicStreamStats { | |||
| 990 | 1014 | // Creates an immediately disconnected QuicStreamStats object. Used when | |
| 991 | 1015 | // lazily creating stats for a stream that has already been destroyed. | |
| 992 | 1016 | static [kCreateDisconnected]() { | |
| 993 | - const count = IDX_STATS_STREAM_FINAL_SIZE + 1; | ||
| 1017 | + const count = IDX_STATS_STREAM_COUNT; | ||
| 994 | 1018 | const stats = new QuicStreamStats(kPrivateConstructor, new BigUint64Array(count), 0); | |
| 995 | 1019 | stats.#disconnected = true; | |
| 996 | 1020 | return stats; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -179,6 +179,11 @@ class DataQueueImpl final : public DataQueue, | |||
| 179 | 179 | for (auto& listener : backpressure_listeners_) listener->EntryRead(amount); | |
| 180 | 180 | } | |
| 181 | 181 | ||
| 182 | + void NotifyBeforePull() { | ||
| 183 | + if (idempotent_) return; | ||
| 184 | + for (auto& listener : backpressure_listeners_) listener->BeforePull(); | ||
| 185 | + } | ||
| 186 | + | ||
| 182 | 187 | bool HasBackpressureListeners() const noexcept { | |
| 183 | 188 | return !backpressure_listeners_.empty(); | |
| 184 | 189 | } | |
@@ -381,6 +386,11 @@ class NonIdempotentDataQueueReader final | |||
| 381 | 386 | size_t max_count_hint = bob::kMaxCountHint) override { | |
| 382 | 387 | std::shared_ptr<DataQueue::Reader> self = shared_from_this(); | |
| 383 | 388 | ||
| 389 | + // Let listeners flush pending data before we check the entries list. | ||
| 390 | + // This allows, for example, the QUIC Stream to flush its receive | ||
| 391 | + // accumulation buffer into the queue before the pull proceeds. | ||
| 392 | + data_queue_->NotifyBeforePull(); | ||
| 393 | + | ||
| 384 | 394 | // If ended is true, this reader has already reached the end and cannot | |
| 385 | 395 | // provide any more data. | |
| 386 | 396 | if (ended_) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -147,6 +147,11 @@ class DataQueue : public MemoryRetainer { | |||
| 147 | 147 | class BackpressureListener { | |
| 148 | 148 | public: | |
| 149 | 149 | virtual void EntryRead(size_t amount) = 0; | |
| 150 | + | ||
| 151 | + // Called before the reader pulls from the DataQueue. Gives | ||
| 152 | + // the listener a chance to flush pending data into the queue | ||
| 153 | + // before the pull checks the entries list. | ||
| 154 | + virtual void BeforePull() {} | ||
| 150 | 155 | }; | |
| 151 | 156 | ||
| 152 | 157 | // A DataQueue::Entry represents a logical chunk of data in the queue. | |
| Back | FazBrowse Home | New Git URL |
0 commit comments