grpc 1.59.0 → 1.59.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +7 -1
- data/src/core/ext/filters/http/server/http_server_filter.cc +21 -17
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +504 -361
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +11 -1
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +9 -0
- data/src/core/ext/transport/chttp2/transport/internal.h +92 -28
- data/src/core/ext/transport/chttp2/transport/max_concurrent_streams_policy.cc +44 -0
- data/src/core/ext/transport/chttp2/transport/max_concurrent_streams_policy.h +67 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +103 -14
- data/src/core/ext/transport/chttp2/transport/ping_callbacks.cc +108 -0
- data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +115 -0
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +26 -4
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +16 -1
- data/src/core/ext/transport/chttp2/transport/write_size_policy.cc +60 -0
- data/src/core/ext/transport/chttp2/transport/write_size_policy.h +66 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +149 -77
- data/src/core/lib/channel/promise_based_filter.cc +9 -4
- data/src/core/lib/channel/promise_based_filter.h +2 -1
- data/src/core/lib/experiments/experiments.cc +222 -0
- data/src/core/lib/experiments/experiments.h +135 -0
- data/src/core/lib/iomgr/combiner.cc +3 -0
- data/src/core/lib/transport/metadata_batch.h +11 -1
- data/src/core/lib/transport/transport.h +6 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +9 -3
@@ -20,6 +20,7 @@
|
|
20
20
|
|
21
21
|
#include "src/core/ext/transport/chttp2/transport/frame_ping.h"
|
22
22
|
|
23
|
+
#include <inttypes.h>
|
23
24
|
#include <string.h>
|
24
25
|
|
25
26
|
#include <algorithm>
|
@@ -35,6 +36,7 @@
|
|
35
36
|
|
36
37
|
#include "src/core/ext/transport/chttp2/transport/internal.h"
|
37
38
|
#include "src/core/ext/transport/chttp2/transport/ping_abuse_policy.h"
|
39
|
+
#include "src/core/ext/transport/chttp2/transport/ping_callbacks.h"
|
38
40
|
#include "src/core/lib/debug/trace.h"
|
39
41
|
|
40
42
|
extern grpc_core::TraceFlag grpc_keepalive_trace;
|
@@ -96,18 +98,26 @@ grpc_error_handle grpc_chttp2_ping_parser_parse(void* parser,
|
|
96
98
|
if (p->byte == 8) {
|
97
99
|
GPR_ASSERT(is_last);
|
98
100
|
if (p->is_ack) {
|
101
|
+
if (grpc_ping_trace.enabled()) {
|
102
|
+
gpr_log(GPR_INFO, "%s[%p]: received ping ack %" PRIx64,
|
103
|
+
t->is_client ? "CLIENT" : "SERVER", t, p->opaque_8bytes);
|
104
|
+
}
|
99
105
|
grpc_chttp2_ack_ping(t, p->opaque_8bytes);
|
100
106
|
} else {
|
101
107
|
if (!t->is_client) {
|
102
108
|
const bool transport_idle =
|
103
109
|
t->keepalive_permit_without_calls == 0 && t->stream_map.empty();
|
104
110
|
if (grpc_keepalive_trace.enabled() || grpc_http_trace.enabled()) {
|
105
|
-
gpr_log(GPR_INFO, "
|
111
|
+
gpr_log(GPR_INFO, "SERVER[%p]: received ping %" PRIx64 ": %s", t,
|
112
|
+
p->opaque_8bytes,
|
106
113
|
t->ping_abuse_policy.GetDebugString(transport_idle).c_str());
|
107
114
|
}
|
108
115
|
if (t->ping_abuse_policy.ReceivedOnePing(transport_idle)) {
|
109
116
|
grpc_chttp2_exceeded_ping_strikes(t);
|
110
117
|
}
|
118
|
+
} else if (grpc_ping_trace.enabled()) {
|
119
|
+
gpr_log(GPR_INFO, "CLIENT[%p]: received ping %" PRIx64, t,
|
120
|
+
p->opaque_8bytes);
|
111
121
|
}
|
112
122
|
if (t->ack_pings) {
|
113
123
|
if (t->ping_ack_count == t->ping_ack_capacity) {
|
@@ -24,6 +24,7 @@
|
|
24
24
|
|
25
25
|
#include <initializer_list>
|
26
26
|
|
27
|
+
#include "absl/random/distributions.h"
|
27
28
|
#include "absl/status/status.h"
|
28
29
|
#include "absl/strings/str_cat.h"
|
29
30
|
#include "absl/strings/str_format.h"
|
@@ -34,7 +35,9 @@
|
|
34
35
|
#include "src/core/ext/transport/chttp2/transport/http_trace.h"
|
35
36
|
#include "src/core/ext/transport/chttp2/transport/internal.h"
|
36
37
|
#include "src/core/ext/transport/chttp2/transport/legacy_frame.h"
|
38
|
+
#include "src/core/ext/transport/chttp2/transport/ping_callbacks.h"
|
37
39
|
#include "src/core/lib/debug/trace.h"
|
40
|
+
#include "src/core/lib/experiments/experiments.h"
|
38
41
|
#include "src/core/lib/gprpp/status_helper.h"
|
39
42
|
#include "src/core/lib/transport/http2_errors.h"
|
40
43
|
#include "src/core/lib/transport/metadata_batch.h"
|
@@ -125,6 +128,12 @@ grpc_error_handle grpc_chttp2_rst_stream_parser_parse(void* parser,
|
|
125
128
|
grpc_core::StatusIntProperty::kHttp2Error,
|
126
129
|
static_cast<intptr_t>(reason));
|
127
130
|
}
|
131
|
+
if (grpc_core::IsPingOnRstStreamEnabled() && !t->is_client &&
|
132
|
+
absl::Bernoulli(t->bitgen, t->ping_on_rst_stream_percent / 100.0)) {
|
133
|
+
++t->num_pending_induced_frames;
|
134
|
+
t->ping_callbacks.RequestPing();
|
135
|
+
grpc_chttp2_initiate_write(t, GRPC_CHTTP2_INITIATE_WRITE_KEEPALIVE_PING);
|
136
|
+
}
|
128
137
|
grpc_chttp2_mark_stream_closed(t, s, true, true, error);
|
129
138
|
}
|
130
139
|
|
@@ -24,13 +24,17 @@
|
|
24
24
|
#include <stddef.h>
|
25
25
|
#include <stdint.h>
|
26
26
|
|
27
|
+
#include <atomic>
|
27
28
|
#include <memory>
|
29
|
+
#include <utility>
|
28
30
|
|
29
31
|
#include "absl/container/flat_hash_map.h"
|
30
32
|
#include "absl/meta/type_traits.h"
|
31
33
|
#include "absl/random/random.h"
|
34
|
+
#include "absl/status/status.h"
|
32
35
|
#include "absl/strings/string_view.h"
|
33
36
|
#include "absl/types/optional.h"
|
37
|
+
#include "absl/types/variant.h"
|
34
38
|
|
35
39
|
#include <grpc/event_engine/event_engine.h>
|
36
40
|
#include <grpc/event_engine/memory_allocator.h>
|
@@ -49,8 +53,11 @@
|
|
49
53
|
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
|
50
54
|
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
|
51
55
|
#include "src/core/ext/transport/chttp2/transport/legacy_frame.h"
|
56
|
+
#include "src/core/ext/transport/chttp2/transport/max_concurrent_streams_policy.h"
|
52
57
|
#include "src/core/ext/transport/chttp2/transport/ping_abuse_policy.h"
|
58
|
+
#include "src/core/ext/transport/chttp2/transport/ping_callbacks.h"
|
53
59
|
#include "src/core/ext/transport/chttp2/transport/ping_rate_policy.h"
|
60
|
+
#include "src/core/ext/transport/chttp2/transport/write_size_policy.h"
|
54
61
|
#include "src/core/lib/channel/channel_args.h"
|
55
62
|
#include "src/core/lib/channel/channelz.h"
|
56
63
|
#include "src/core/lib/debug/trace.h"
|
@@ -145,18 +152,6 @@ typedef enum {
|
|
145
152
|
const char* grpc_chttp2_initiate_write_reason_string(
|
146
153
|
grpc_chttp2_initiate_write_reason reason);
|
147
154
|
|
148
|
-
struct grpc_chttp2_ping_queue {
|
149
|
-
grpc_closure_list lists[GRPC_CHTTP2_PCL_COUNT] = {};
|
150
|
-
uint64_t inflight_id = 0;
|
151
|
-
};
|
152
|
-
|
153
|
-
struct grpc_chttp2_repeated_ping_state {
|
154
|
-
grpc_core::Timestamp last_ping_sent_time;
|
155
|
-
int pings_before_data_required;
|
156
|
-
absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle>
|
157
|
-
delayed_ping_timer_handle;
|
158
|
-
};
|
159
|
-
|
160
155
|
// deframer state for the overall http2 stream of bytes
|
161
156
|
typedef enum {
|
162
157
|
// prefix: one entry per http2 connection prefix byte
|
@@ -283,6 +278,31 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
283
278
|
|
284
279
|
/// maps stream id to grpc_chttp2_stream objects
|
285
280
|
absl::flat_hash_map<uint32_t, grpc_chttp2_stream*> stream_map;
|
281
|
+
// Count of streams that should be counted against max concurrent streams but
|
282
|
+
// are not in stream_map (due to tarpitting).
|
283
|
+
size_t extra_streams = 0;
|
284
|
+
|
285
|
+
class RemovedStreamHandle {
|
286
|
+
public:
|
287
|
+
RemovedStreamHandle() = default;
|
288
|
+
explicit RemovedStreamHandle(
|
289
|
+
grpc_core::RefCountedPtr<grpc_chttp2_transport> t)
|
290
|
+
: transport_(std::move(t)) {
|
291
|
+
++transport_->extra_streams;
|
292
|
+
}
|
293
|
+
~RemovedStreamHandle() {
|
294
|
+
if (transport_ != nullptr) {
|
295
|
+
--transport_->extra_streams;
|
296
|
+
}
|
297
|
+
}
|
298
|
+
RemovedStreamHandle(const RemovedStreamHandle&) = delete;
|
299
|
+
RemovedStreamHandle& operator=(const RemovedStreamHandle&) = delete;
|
300
|
+
RemovedStreamHandle(RemovedStreamHandle&&) = default;
|
301
|
+
RemovedStreamHandle& operator=(RemovedStreamHandle&&) = default;
|
302
|
+
|
303
|
+
private:
|
304
|
+
grpc_core::RefCountedPtr<grpc_chttp2_transport> transport_;
|
305
|
+
};
|
286
306
|
|
287
307
|
grpc_closure write_action_begin_locked;
|
288
308
|
grpc_closure write_action;
|
@@ -311,13 +331,15 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
311
331
|
grpc_core::ConnectivityStateTracker state_tracker;
|
312
332
|
|
313
333
|
/// data to write now
|
314
|
-
|
334
|
+
grpc_core::SliceBuffer outbuf;
|
315
335
|
/// hpack encoding
|
316
336
|
grpc_core::HPackCompressor hpack_compressor;
|
317
337
|
|
318
338
|
/// data to write next write
|
319
339
|
grpc_slice_buffer qbuf;
|
320
340
|
|
341
|
+
size_t max_requests_per_read;
|
342
|
+
|
321
343
|
/// Set to a grpc_error object if a goaway frame is received. By default, set
|
322
344
|
/// to absl::OkStatus()
|
323
345
|
grpc_error_handle goaway_error;
|
@@ -331,6 +353,10 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
331
353
|
/// settings values
|
332
354
|
uint32_t settings[GRPC_NUM_SETTING_SETS][GRPC_CHTTP2_NUM_SETTINGS];
|
333
355
|
|
356
|
+
grpc_event_engine::experimental::EventEngine::TaskHandle
|
357
|
+
settings_ack_watchdog =
|
358
|
+
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid;
|
359
|
+
|
334
360
|
/// what is the next stream id to be allocated by this peer?
|
335
361
|
/// copied to next_stream_id in parsing when parsing commences
|
336
362
|
uint32_t next_stream_id = 0;
|
@@ -338,15 +364,19 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
338
364
|
/// last new stream id
|
339
365
|
uint32_t last_new_stream_id = 0;
|
340
366
|
|
367
|
+
/// Number of incoming streams allowed before a settings ACK is required
|
368
|
+
uint32_t num_incoming_streams_before_settings_ack = 0;
|
369
|
+
|
341
370
|
/// ping queues for various ping insertion points
|
342
|
-
grpc_chttp2_ping_queue ping_queue = grpc_chttp2_ping_queue();
|
343
371
|
grpc_core::Chttp2PingAbusePolicy ping_abuse_policy;
|
344
372
|
grpc_core::Chttp2PingRatePolicy ping_rate_policy;
|
373
|
+
grpc_core::Chttp2PingCallbacks ping_callbacks;
|
345
374
|
absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle>
|
346
375
|
delayed_ping_timer_handle;
|
347
|
-
uint64_t ping_ctr = 0; // unique id for pings
|
348
376
|
grpc_closure retry_initiate_ping_locked;
|
349
377
|
|
378
|
+
grpc_core::Chttp2MaxConcurrentStreamsPolicy max_concurrent_streams_policy;
|
379
|
+
|
350
380
|
/// ping acks
|
351
381
|
size_t ping_ack_count = 0;
|
352
382
|
size_t ping_ack_capacity = 0;
|
@@ -379,6 +409,10 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
379
409
|
uint32_t expect_continuation_stream_id = 0;
|
380
410
|
uint32_t incoming_frame_size = 0;
|
381
411
|
|
412
|
+
int min_tarpit_duration_ms;
|
413
|
+
int max_tarpit_duration_ms;
|
414
|
+
bool allow_tarpit;
|
415
|
+
|
382
416
|
grpc_chttp2_stream* incoming_stream = nullptr;
|
383
417
|
// active parser
|
384
418
|
struct Parser {
|
@@ -425,13 +459,13 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
425
459
|
/// timer to initiate ping events
|
426
460
|
absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle>
|
427
461
|
keepalive_ping_timer_handle;
|
428
|
-
/// watchdog to kill the transport when waiting for the keepalive ping
|
429
|
-
absl::optional<grpc_event_engine::experimental::EventEngine::TaskHandle>
|
430
|
-
keepalive_watchdog_timer_handle;
|
431
462
|
/// time duration in between pings
|
432
463
|
grpc_core::Duration keepalive_time;
|
433
|
-
/// grace period for a ping
|
464
|
+
/// grace period to wait for data after sending a ping before keepalives
|
465
|
+
/// timeout
|
434
466
|
grpc_core::Duration keepalive_timeout;
|
467
|
+
/// number of stream objects currently allocated by this transport
|
468
|
+
std::atomic<size_t> streams_allocated{0};
|
435
469
|
/// keep-alive state machine state
|
436
470
|
grpc_chttp2_keepalive_state keepalive_state;
|
437
471
|
// Soft limit on max header size.
|
@@ -447,10 +481,20 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
447
481
|
uint32_t num_pending_induced_frames = 0;
|
448
482
|
uint32_t incoming_stream_id = 0;
|
449
483
|
|
484
|
+
/// grace period after sending a ping to wait for the ping ack
|
485
|
+
grpc_core::Duration ping_timeout;
|
486
|
+
grpc_event_engine::experimental::EventEngine::TaskHandle
|
487
|
+
keepalive_ping_timeout_handle =
|
488
|
+
grpc_event_engine::experimental::EventEngine::TaskHandle::kInvalid;
|
489
|
+
/// grace period before settings timeout expires
|
490
|
+
grpc_core::Duration settings_timeout;
|
491
|
+
|
450
492
|
/// how much data are we willing to buffer when the WRITE_BUFFER_HINT is set?
|
451
|
-
///
|
452
493
|
uint32_t write_buffer_size = grpc_core::chttp2::kDefaultWindow;
|
453
494
|
|
495
|
+
/// policy for how much data we're willing to put into one http2 write
|
496
|
+
grpc_core::Chttp2WriteSizePolicy write_size_policy;
|
497
|
+
|
454
498
|
bool reading_paused_on_pending_induced_frames = false;
|
455
499
|
/// Based on channel args, preferred_rx_crypto_frame_sizes are advertised to
|
456
500
|
/// the peer
|
@@ -492,6 +536,12 @@ struct grpc_chttp2_transport : public grpc_core::KeepsGrpcInitialized {
|
|
492
536
|
bool bdp_ping_started = false;
|
493
537
|
// True if pings should be acked
|
494
538
|
bool ack_pings = true;
|
539
|
+
/// True if the keepalive system wants to see some data incoming
|
540
|
+
bool keepalive_incoming_data_wanted = false;
|
541
|
+
|
542
|
+
// What percentage of rst_stream frames on the server should cause a ping
|
543
|
+
// frame to be generated.
|
544
|
+
uint8_t ping_on_rst_stream_percent;
|
495
545
|
|
496
546
|
/// write execution state of the transport
|
497
547
|
grpc_chttp2_write_state write_state = GRPC_CHTTP2_WRITE_STATE_IDLE;
|
@@ -618,6 +668,8 @@ struct grpc_chttp2_stream {
|
|
618
668
|
bool traced = false;
|
619
669
|
};
|
620
670
|
|
671
|
+
#define GRPC_ARG_PING_TIMEOUT_MS "grpc.http2.ping_timeout_ms"
|
672
|
+
|
621
673
|
/// Transport writing call flow:
|
622
674
|
/// grpc_chttp2_initiate_write() is called anywhere that we know bytes need to
|
623
675
|
/// go out on the wire.
|
@@ -645,10 +697,14 @@ grpc_chttp2_begin_write_result grpc_chttp2_begin_write(
|
|
645
697
|
grpc_chttp2_transport* t);
|
646
698
|
void grpc_chttp2_end_write(grpc_chttp2_transport* t, grpc_error_handle error);
|
647
699
|
|
648
|
-
/// Process one slice of incoming data
|
649
|
-
///
|
650
|
-
|
651
|
-
|
700
|
+
/// Process one slice of incoming data
|
701
|
+
/// Returns:
|
702
|
+
/// - a count of parsed bytes in the event of a partial read: the caller should
|
703
|
+
/// offload responsibilities to another thread to continue parsing.
|
704
|
+
/// - or a status in the case of a completed read
|
705
|
+
absl::variant<size_t, absl::Status> grpc_chttp2_perform_read(
|
706
|
+
grpc_chttp2_transport* t, const grpc_slice& slice,
|
707
|
+
size_t& requests_started);
|
652
708
|
|
653
709
|
bool grpc_chttp2_list_add_writable_stream(grpc_chttp2_transport* t,
|
654
710
|
grpc_chttp2_stream* s);
|
@@ -723,6 +779,14 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
|
|
723
779
|
const char* desc,
|
724
780
|
grpc_core::DebugLocation whence = {});
|
725
781
|
|
782
|
+
void grpc_chttp2_keepalive_timeout(
|
783
|
+
grpc_core::RefCountedPtr<grpc_chttp2_transport> t);
|
784
|
+
void grpc_chttp2_ping_timeout(
|
785
|
+
grpc_core::RefCountedPtr<grpc_chttp2_transport> t);
|
786
|
+
|
787
|
+
void grpc_chttp2_settings_timeout(
|
788
|
+
grpc_core::RefCountedPtr<grpc_chttp2_transport> t);
|
789
|
+
|
726
790
|
#define GRPC_HEADER_SIZE_IN_BYTES 5
|
727
791
|
#define MAX_SIZE_T (~(size_t)0)
|
728
792
|
|
@@ -742,9 +806,9 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
|
|
742
806
|
void grpc_chttp2_fake_status(grpc_chttp2_transport* t,
|
743
807
|
grpc_chttp2_stream* stream,
|
744
808
|
grpc_error_handle error);
|
745
|
-
|
746
|
-
|
747
|
-
|
809
|
+
grpc_chttp2_transport::RemovedStreamHandle grpc_chttp2_mark_stream_closed(
|
810
|
+
grpc_chttp2_transport* t, grpc_chttp2_stream* s, int close_reads,
|
811
|
+
int close_writes, grpc_error_handle error);
|
748
812
|
void grpc_chttp2_start_writing(grpc_chttp2_transport* t);
|
749
813
|
|
750
814
|
#ifndef NDEBUG
|
@@ -780,7 +844,7 @@ void grpc_chttp2_mark_stream_writable(grpc_chttp2_transport* t,
|
|
780
844
|
grpc_chttp2_stream* s);
|
781
845
|
|
782
846
|
void grpc_chttp2_cancel_stream(grpc_chttp2_transport* t, grpc_chttp2_stream* s,
|
783
|
-
grpc_error_handle due_to_error);
|
847
|
+
grpc_error_handle due_to_error, bool tarpit);
|
784
848
|
|
785
849
|
void grpc_chttp2_maybe_complete_recv_initial_metadata(grpc_chttp2_transport* t,
|
786
850
|
grpc_chttp2_stream* s);
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// Copyright 2023 gRPC authors.
|
2
|
+
//
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
// you may not use this file except in compliance with the License.
|
5
|
+
// You may obtain a copy of the License at
|
6
|
+
//
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
//
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
// See the License for the specific language governing permissions and
|
13
|
+
// limitations under the License.
|
14
|
+
|
15
|
+
#include <grpc/support/port_platform.h>
|
16
|
+
|
17
|
+
#include "src/core/ext/transport/chttp2/transport/max_concurrent_streams_policy.h"
|
18
|
+
|
19
|
+
#include <utility>
|
20
|
+
|
21
|
+
#include <grpc/support/log.h>
|
22
|
+
|
23
|
+
namespace grpc_core {
|
24
|
+
|
25
|
+
void Chttp2MaxConcurrentStreamsPolicy::AddDemerit() {
|
26
|
+
++new_demerits_;
|
27
|
+
++unacked_demerits_;
|
28
|
+
}
|
29
|
+
|
30
|
+
void Chttp2MaxConcurrentStreamsPolicy::FlushedSettings() {
|
31
|
+
sent_demerits_ += std::exchange(new_demerits_, 0);
|
32
|
+
}
|
33
|
+
|
34
|
+
void Chttp2MaxConcurrentStreamsPolicy::AckLastSend() {
|
35
|
+
GPR_ASSERT(unacked_demerits_ >= sent_demerits_);
|
36
|
+
unacked_demerits_ -= std::exchange(sent_demerits_, 0);
|
37
|
+
}
|
38
|
+
|
39
|
+
uint32_t Chttp2MaxConcurrentStreamsPolicy::AdvertiseValue() const {
|
40
|
+
if (target_ < unacked_demerits_) return 0;
|
41
|
+
return target_ - unacked_demerits_;
|
42
|
+
}
|
43
|
+
|
44
|
+
} // namespace grpc_core
|
@@ -0,0 +1,67 @@
|
|
1
|
+
// Copyright 2023 gRPC authors.
|
2
|
+
//
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
// you may not use this file except in compliance with the License.
|
5
|
+
// You may obtain a copy of the License at
|
6
|
+
//
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
//
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
// See the License for the specific language governing permissions and
|
13
|
+
// limitations under the License.
|
14
|
+
|
15
|
+
#ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_MAX_CONCURRENT_STREAMS_POLICY_H
|
16
|
+
#define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_MAX_CONCURRENT_STREAMS_POLICY_H
|
17
|
+
|
18
|
+
#include <grpc/support/port_platform.h>
|
19
|
+
|
20
|
+
#include <cstdint>
|
21
|
+
#include <limits>
|
22
|
+
|
23
|
+
namespace grpc_core {
|
24
|
+
|
25
|
+
class Chttp2MaxConcurrentStreamsPolicy {
|
26
|
+
public:
|
27
|
+
// Set the target number of concurrent streams.
|
28
|
+
// If everything is idle we should advertise this number.
|
29
|
+
void SetTarget(uint32_t target) { target_ = target; }
|
30
|
+
|
31
|
+
// Add one demerit to the current target.
|
32
|
+
// We need to do one full settings round trip after this to clear this
|
33
|
+
// demerit.
|
34
|
+
// It will reduce our advertised max concurrent streams by one.
|
35
|
+
void AddDemerit();
|
36
|
+
|
37
|
+
// Notify the policy that we've sent a settings frame.
|
38
|
+
// Newly added demerits since the last settings frame was sent will be cleared
|
39
|
+
// once that settings frame is acknowledged.
|
40
|
+
void FlushedSettings();
|
41
|
+
|
42
|
+
// Notify the policy that we've received an acknowledgement for the last
|
43
|
+
// settings frame we sent.
|
44
|
+
void AckLastSend();
|
45
|
+
|
46
|
+
// Returns what we should advertise as max concurrent streams.
|
47
|
+
uint32_t AdvertiseValue() const;
|
48
|
+
|
49
|
+
private:
|
50
|
+
uint32_t target_ = std::numeric_limits<int32_t>::max();
|
51
|
+
// Demerit flow:
|
52
|
+
// When we add a demerit, we add to both new & unacked.
|
53
|
+
// When we flush settings, we move new to sent.
|
54
|
+
// When we ack settings, we remove what we sent from unacked.
|
55
|
+
// eg:
|
56
|
+
// we add 10 demerits - now new=10, sent=0, unacked=10
|
57
|
+
// we send settings - now new=0, sent=10, unacked=10
|
58
|
+
// we add 5 demerits - now new=5, sent=10, unacked=15
|
59
|
+
// we get the settings ack - now new=5, sent=0, unacked=5
|
60
|
+
uint32_t new_demerits_ = 0;
|
61
|
+
uint32_t sent_demerits_ = 0;
|
62
|
+
uint32_t unacked_demerits_ = 0;
|
63
|
+
};
|
64
|
+
|
65
|
+
} // namespace grpc_core
|
66
|
+
|
67
|
+
#endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_MAX_CONCURRENT_STREAMS_POLICY_H
|