grpc 1.59.0 → 1.59.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|