[server] Allow configuring max incoming connections at the server (#36088)
Closes #36088
COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/36088 from Vignesh2208:server-fix e62a8f7ae7
PiperOrigin-RevId: 614729878
This commit is contained in:
parent
f8cfe1c16d
commit
7533328075
|
|
@ -2383,6 +2383,7 @@ add_library(grpc
|
|||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/api.cc
|
||||
src/core/lib/resource_quota/arena.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -3145,6 +3146,7 @@ add_library(grpc_unsecure
|
|||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/api.cc
|
||||
src/core/lib/resource_quota/arena.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -5252,6 +5254,7 @@ add_library(grpc_authorization_provider
|
|||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/api.cc
|
||||
src/core/lib/resource_quota/arena.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -10177,6 +10180,7 @@ add_executable(chunked_vector_test
|
|||
src/core/lib/promise/activity.cc
|
||||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/arena.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -14175,6 +14179,7 @@ add_executable(flow_control_test
|
|||
src/core/lib/iomgr/iomgr_internal.cc
|
||||
src/core/lib/promise/activity.cc
|
||||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -14263,6 +14268,7 @@ add_executable(for_each_test
|
|||
src/core/lib/promise/activity.cc
|
||||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/arena.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -17709,6 +17715,7 @@ add_executable(interceptor_list_test
|
|||
src/core/lib/promise/activity.cc
|
||||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/arena.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -18900,6 +18907,7 @@ add_executable(map_pipe_test
|
|||
src/core/lib/promise/activity.cc
|
||||
src/core/lib/promise/trace.cc
|
||||
src/core/lib/resource_quota/arena.cc
|
||||
src/core/lib/resource_quota/connection_quota.cc
|
||||
src/core/lib/resource_quota/memory_quota.cc
|
||||
src/core/lib/resource_quota/periodic_update.cc
|
||||
src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
|
|||
|
|
@ -1309,6 +1309,7 @@ LIBGRPC_SRC = \
|
|||
src/core/lib/promise/trace.cc \
|
||||
src/core/lib/resource_quota/api.cc \
|
||||
src/core/lib/resource_quota/arena.cc \
|
||||
src/core/lib/resource_quota/connection_quota.cc \
|
||||
src/core/lib/resource_quota/memory_quota.cc \
|
||||
src/core/lib/resource_quota/periodic_update.cc \
|
||||
src/core/lib/resource_quota/resource_quota.cc \
|
||||
|
|
|
|||
|
|
@ -1608,6 +1608,8 @@ let package = Package(
|
|||
"src/core/lib/resource_quota/api.h",
|
||||
"src/core/lib/resource_quota/arena.cc",
|
||||
"src/core/lib/resource_quota/arena.h",
|
||||
"src/core/lib/resource_quota/connection_quota.cc",
|
||||
"src/core/lib/resource_quota/connection_quota.h",
|
||||
"src/core/lib/resource_quota/memory_quota.cc",
|
||||
"src/core/lib/resource_quota/memory_quota.h",
|
||||
"src/core/lib/resource_quota/periodic_update.cc",
|
||||
|
|
|
|||
|
|
@ -1041,6 +1041,7 @@ libs:
|
|||
- src/core/lib/promise/try_seq.h
|
||||
- src/core/lib/resource_quota/api.h
|
||||
- src/core/lib/resource_quota/arena.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -1837,6 +1838,7 @@ libs:
|
|||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/api.cc
|
||||
- src/core/lib/resource_quota/arena.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -2542,6 +2544,7 @@ libs:
|
|||
- src/core/lib/promise/try_seq.h
|
||||
- src/core/lib/resource_quota/api.h
|
||||
- src/core/lib/resource_quota/arena.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -2961,6 +2964,7 @@ libs:
|
|||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/api.cc
|
||||
- src/core/lib/resource_quota/arena.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -4619,6 +4623,7 @@ libs:
|
|||
- src/core/lib/promise/try_seq.h
|
||||
- src/core/lib/resource_quota/api.h
|
||||
- src/core/lib/resource_quota/arena.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -4916,6 +4921,7 @@ libs:
|
|||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/api.cc
|
||||
- src/core/lib/resource_quota/arena.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -7689,6 +7695,7 @@ targets:
|
|||
- src/core/lib/promise/seq.h
|
||||
- src/core/lib/promise/trace.h
|
||||
- src/core/lib/resource_quota/arena.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -7738,6 +7745,7 @@ targets:
|
|||
- src/core/lib/promise/activity.cc
|
||||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/arena.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -9785,6 +9793,7 @@ targets:
|
|||
- src/core/lib/promise/race.h
|
||||
- src/core/lib/promise/seq.h
|
||||
- src/core/lib/promise/trace.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -9839,6 +9848,7 @@ targets:
|
|||
- src/core/lib/iomgr/iomgr_internal.cc
|
||||
- src/core/lib/promise/activity.cc
|
||||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -9928,6 +9938,7 @@ targets:
|
|||
- src/core/lib/promise/trace.h
|
||||
- src/core/lib/promise/try_seq.h
|
||||
- src/core/lib/resource_quota/arena.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -9978,6 +9989,7 @@ targets:
|
|||
- src/core/lib/promise/activity.cc
|
||||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/arena.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -11578,6 +11590,7 @@ targets:
|
|||
- src/core/lib/promise/seq.h
|
||||
- src/core/lib/promise/trace.h
|
||||
- src/core/lib/resource_quota/arena.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -11628,6 +11641,7 @@ targets:
|
|||
- src/core/lib/promise/activity.cc
|
||||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/arena.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
@ -12256,6 +12270,7 @@ targets:
|
|||
- src/core/lib/promise/trace.h
|
||||
- src/core/lib/promise/try_seq.h
|
||||
- src/core/lib/resource_quota/arena.h
|
||||
- src/core/lib/resource_quota/connection_quota.h
|
||||
- src/core/lib/resource_quota/memory_quota.h
|
||||
- src/core/lib/resource_quota/periodic_update.h
|
||||
- src/core/lib/resource_quota/resource_quota.h
|
||||
|
|
@ -12306,6 +12321,7 @@ targets:
|
|||
- src/core/lib/promise/activity.cc
|
||||
- src/core/lib/promise/trace.cc
|
||||
- src/core/lib/resource_quota/arena.cc
|
||||
- src/core/lib/resource_quota/connection_quota.cc
|
||||
- src/core/lib/resource_quota/memory_quota.cc
|
||||
- src/core/lib/resource_quota/periodic_update.cc
|
||||
- src/core/lib/resource_quota/resource_quota.cc
|
||||
|
|
|
|||
|
|
@ -684,6 +684,7 @@ if test "$PHP_GRPC" != "no"; then
|
|||
src/core/lib/promise/trace.cc \
|
||||
src/core/lib/resource_quota/api.cc \
|
||||
src/core/lib/resource_quota/arena.cc \
|
||||
src/core/lib/resource_quota/connection_quota.cc \
|
||||
src/core/lib/resource_quota/memory_quota.cc \
|
||||
src/core/lib/resource_quota/periodic_update.cc \
|
||||
src/core/lib/resource_quota/resource_quota.cc \
|
||||
|
|
|
|||
|
|
@ -649,6 +649,7 @@ if (PHP_GRPC != "no") {
|
|||
"src\\core\\lib\\promise\\trace.cc " +
|
||||
"src\\core\\lib\\resource_quota\\api.cc " +
|
||||
"src\\core\\lib\\resource_quota\\arena.cc " +
|
||||
"src\\core\\lib\\resource_quota\\connection_quota.cc " +
|
||||
"src\\core\\lib\\resource_quota\\memory_quota.cc " +
|
||||
"src\\core\\lib\\resource_quota\\periodic_update.cc " +
|
||||
"src\\core\\lib\\resource_quota\\resource_quota.cc " +
|
||||
|
|
|
|||
|
|
@ -1147,6 +1147,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/promise/try_seq.h',
|
||||
'src/core/lib/resource_quota/api.h',
|
||||
'src/core/lib/resource_quota/arena.h',
|
||||
'src/core/lib/resource_quota/connection_quota.h',
|
||||
'src/core/lib/resource_quota/memory_quota.h',
|
||||
'src/core/lib/resource_quota/periodic_update.h',
|
||||
'src/core/lib/resource_quota/resource_quota.h',
|
||||
|
|
@ -2410,6 +2411,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/promise/try_seq.h',
|
||||
'src/core/lib/resource_quota/api.h',
|
||||
'src/core/lib/resource_quota/arena.h',
|
||||
'src/core/lib/resource_quota/connection_quota.h',
|
||||
'src/core/lib/resource_quota/memory_quota.h',
|
||||
'src/core/lib/resource_quota/periodic_update.h',
|
||||
'src/core/lib/resource_quota/resource_quota.h',
|
||||
|
|
|
|||
|
|
@ -1722,6 +1722,8 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/resource_quota/api.h',
|
||||
'src/core/lib/resource_quota/arena.cc',
|
||||
'src/core/lib/resource_quota/arena.h',
|
||||
'src/core/lib/resource_quota/connection_quota.cc',
|
||||
'src/core/lib/resource_quota/connection_quota.h',
|
||||
'src/core/lib/resource_quota/memory_quota.cc',
|
||||
'src/core/lib/resource_quota/memory_quota.h',
|
||||
'src/core/lib/resource_quota/periodic_update.cc',
|
||||
|
|
@ -3191,6 +3193,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/promise/try_seq.h',
|
||||
'src/core/lib/resource_quota/api.h',
|
||||
'src/core/lib/resource_quota/arena.h',
|
||||
'src/core/lib/resource_quota/connection_quota.h',
|
||||
'src/core/lib/resource_quota/memory_quota.h',
|
||||
'src/core/lib/resource_quota/periodic_update.h',
|
||||
'src/core/lib/resource_quota/resource_quota.h',
|
||||
|
|
|
|||
|
|
@ -1614,6 +1614,8 @@ Gem::Specification.new do |s|
|
|||
s.files += %w( src/core/lib/resource_quota/api.h )
|
||||
s.files += %w( src/core/lib/resource_quota/arena.cc )
|
||||
s.files += %w( src/core/lib/resource_quota/arena.h )
|
||||
s.files += %w( src/core/lib/resource_quota/connection_quota.cc )
|
||||
s.files += %w( src/core/lib/resource_quota/connection_quota.h )
|
||||
s.files += %w( src/core/lib/resource_quota/memory_quota.cc )
|
||||
s.files += %w( src/core/lib/resource_quota/memory_quota.h )
|
||||
s.files += %w( src/core/lib/resource_quota/periodic_update.cc )
|
||||
|
|
|
|||
|
|
@ -883,6 +883,7 @@
|
|||
'src/core/lib/promise/trace.cc',
|
||||
'src/core/lib/resource_quota/api.cc',
|
||||
'src/core/lib/resource_quota/arena.cc',
|
||||
'src/core/lib/resource_quota/connection_quota.cc',
|
||||
'src/core/lib/resource_quota/memory_quota.cc',
|
||||
'src/core/lib/resource_quota/periodic_update.cc',
|
||||
'src/core/lib/resource_quota/resource_quota.cc',
|
||||
|
|
@ -1422,6 +1423,7 @@
|
|||
'src/core/lib/promise/trace.cc',
|
||||
'src/core/lib/resource_quota/api.cc',
|
||||
'src/core/lib/resource_quota/arena.cc',
|
||||
'src/core/lib/resource_quota/connection_quota.cc',
|
||||
'src/core/lib/resource_quota/memory_quota.cc',
|
||||
'src/core/lib/resource_quota/periodic_update.cc',
|
||||
'src/core/lib/resource_quota/resource_quota.cc',
|
||||
|
|
@ -2228,6 +2230,7 @@
|
|||
'src/core/lib/promise/trace.cc',
|
||||
'src/core/lib/resource_quota/api.cc',
|
||||
'src/core/lib/resource_quota/arena.cc',
|
||||
'src/core/lib/resource_quota/connection_quota.cc',
|
||||
'src/core/lib/resource_quota/memory_quota.cc',
|
||||
'src/core/lib/resource_quota/periodic_update.cc',
|
||||
'src/core/lib/resource_quota/resource_quota.cc',
|
||||
|
|
|
|||
|
|
@ -395,6 +395,10 @@
|
|||
* factory. */
|
||||
#define GRPC_ARG_EVENT_ENGINE_USE_MEMORY_ALLOCATOR_FACTORY \
|
||||
"grpc.event_engine_use_memory_allocator_factory"
|
||||
/** Configure the max number of allowed incoming connections to the server.
|
||||
* If unspecified, it is unlimited */
|
||||
#define GRPC_ARG_MAX_ALLOWED_INCOMING_CONNECTIONS \
|
||||
"grpc.max_allowed_incoming_connections"
|
||||
/** \} */
|
||||
|
||||
#endif /* GRPC_IMPL_CHANNEL_ARG_NAMES_H */
|
||||
|
|
|
|||
|
|
@ -1596,6 +1596,8 @@
|
|||
<file baseinstalldir="/" name="src/core/lib/resource_quota/api.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/resource_quota/arena.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/resource_quota/arena.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/resource_quota/connection_quota.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/resource_quota/connection_quota.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/resource_quota/memory_quota.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/resource_quota/memory_quota.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/resource_quota/periodic_update.cc" role="src" />
|
||||
|
|
|
|||
|
|
@ -1399,6 +1399,23 @@ grpc_cc_library(
|
|||
],
|
||||
)
|
||||
|
||||
grpc_cc_library(
|
||||
name = "connection_quota",
|
||||
srcs = [
|
||||
"lib/resource_quota/connection_quota.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"lib/resource_quota/connection_quota.h",
|
||||
],
|
||||
external_deps = ["absl/base:core_headers"],
|
||||
deps = [
|
||||
"memory_quota",
|
||||
"ref_counted",
|
||||
"//:gpr",
|
||||
"//:ref_counted_ptr",
|
||||
],
|
||||
)
|
||||
|
||||
grpc_cc_library(
|
||||
name = "resource_quota_trace",
|
||||
srcs = [
|
||||
|
|
@ -1426,6 +1443,7 @@ grpc_cc_library(
|
|||
"@grpc:alt_grpc_base_legacy",
|
||||
],
|
||||
deps = [
|
||||
"connection_quota",
|
||||
"memory_quota",
|
||||
"ref_counted",
|
||||
"thread_quota",
|
||||
|
|
@ -6747,6 +6765,7 @@ grpc_cc_library(
|
|||
"channel_args",
|
||||
"channel_args_endpoint_config",
|
||||
"closure",
|
||||
"connection_quota",
|
||||
"error",
|
||||
"error_utils",
|
||||
"grpc_insecure_credentials",
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
#include "src/core/lib/iomgr/tcp_server.h"
|
||||
#include "src/core/lib/iomgr/unix_sockets_posix.h"
|
||||
#include "src/core/lib/iomgr/vsock.h"
|
||||
#include "src/core/lib/resource_quota/connection_quota.h"
|
||||
#include "src/core/lib/resource_quota/memory_quota.h"
|
||||
#include "src/core/lib/resource_quota/resource_quota.h"
|
||||
#include "src/core/lib/security/credentials/credentials.h"
|
||||
|
|
@ -283,6 +284,7 @@ class Chttp2ServerListener : public Server::ListenerInterface {
|
|||
grpc_closure* on_destroy_done_ ABSL_GUARDED_BY(mu_) = nullptr;
|
||||
RefCountedPtr<channelz::ListenSocketNode> channelz_listen_socket_;
|
||||
MemoryQuotaRefPtr memory_quota_;
|
||||
ConnectionQuotaRefPtr connection_quota_;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -504,6 +506,18 @@ void Chttp2ServerListener::ActiveConnection::HandshakingState::OnHandshakeDone(
|
|||
} else {
|
||||
// Remove the connection from the connections_ map since OnClose()
|
||||
// will not be invoked when a config fetcher is set.
|
||||
auto connection_quota =
|
||||
self->connection_->listener_->connection_quota_->Ref()
|
||||
.release();
|
||||
auto on_close_transport = [](void* arg,
|
||||
grpc_error_handle /*handle*/) {
|
||||
ConnectionQuota* connection_quota =
|
||||
static_cast<ConnectionQuota*>(arg);
|
||||
connection_quota->ReleaseConnections(1);
|
||||
connection_quota->Unref();
|
||||
};
|
||||
on_close = GRPC_CLOSURE_CREATE(on_close_transport, connection_quota,
|
||||
grpc_schedule_on_exec_ctx_);
|
||||
cleanup_connection = true;
|
||||
}
|
||||
grpc_chttp2_transport_start_reading(transport, args->read_buffer,
|
||||
|
|
@ -658,6 +672,7 @@ void Chttp2ServerListener::ActiveConnection::OnClose(
|
|||
self->drain_grace_timer_handle_.reset();
|
||||
}
|
||||
}
|
||||
self->listener_->connection_quota_->ReleaseConnections(1);
|
||||
self->Unref();
|
||||
}
|
||||
|
||||
|
|
@ -762,7 +777,14 @@ Chttp2ServerListener::Chttp2ServerListener(
|
|||
: server_(server),
|
||||
args_modifier_(args_modifier),
|
||||
args_(args),
|
||||
memory_quota_(args.GetObject<ResourceQuota>()->memory_quota()) {
|
||||
memory_quota_(args.GetObject<ResourceQuota>()->memory_quota()),
|
||||
connection_quota_(MakeRefCounted<ConnectionQuota>()) {
|
||||
auto max_allowed_incoming_connections =
|
||||
args.GetInt(GRPC_ARG_MAX_ALLOWED_INCOMING_CONNECTIONS);
|
||||
if (max_allowed_incoming_connections.has_value()) {
|
||||
connection_quota_->SetMaxIncomingConnections(
|
||||
max_allowed_incoming_connections.value());
|
||||
}
|
||||
GRPC_CLOSURE_INIT(&tcp_server_shutdown_complete_, TcpServerShutdownComplete,
|
||||
this, grpc_schedule_on_exec_ctx);
|
||||
}
|
||||
|
|
@ -821,6 +843,14 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp,
|
|||
grpc_endpoint_destroy(tcp);
|
||||
gpr_free(acceptor);
|
||||
};
|
||||
if (!self->connection_quota_->AllowIncomingConnection(
|
||||
self->memory_quota_, grpc_endpoint_get_peer(tcp))) {
|
||||
grpc_error_handle error = GRPC_ERROR_CREATE(
|
||||
"Rejected incoming connection because configured connection quota "
|
||||
"limits have been exceeded.");
|
||||
endpoint_cleanup(error);
|
||||
return;
|
||||
}
|
||||
if (self->server_->config_fetcher() != nullptr) {
|
||||
if (connection_manager == nullptr) {
|
||||
grpc_error_handle error = GRPC_ERROR_CREATE(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2024 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include "src/core/lib/resource_quota/connection_quota.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
ConnectionQuota::ConnectionQuota() = default;
|
||||
|
||||
void ConnectionQuota::SetMaxIncomingConnections(int max_incoming_connections) {
|
||||
// The maximum can only be configured once.
|
||||
GPR_ASSERT(max_incoming_connections < INT_MAX);
|
||||
GPR_ASSERT(max_incoming_connections_.exchange(max_incoming_connections,
|
||||
std::memory_order_release) ==
|
||||
INT_MAX);
|
||||
}
|
||||
|
||||
// Returns true if the incoming connection is allowed to be accepted on the
|
||||
// server.
|
||||
bool ConnectionQuota::AllowIncomingConnection(MemoryQuotaRefPtr mem_quota,
|
||||
absl::string_view /*peer*/) {
|
||||
if (mem_quota->IsMemoryPressureHigh()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (max_incoming_connections_.load(std::memory_order_relaxed) == INT_MAX) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int curr_active_connections =
|
||||
active_incoming_connections_.load(std::memory_order_acquire);
|
||||
do {
|
||||
if (curr_active_connections >=
|
||||
max_incoming_connections_.load(std::memory_order_relaxed)) {
|
||||
return false;
|
||||
}
|
||||
} while (!active_incoming_connections_.compare_exchange_weak(
|
||||
curr_active_connections, curr_active_connections + 1,
|
||||
std::memory_order_acq_rel, std::memory_order_relaxed));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mark connections as closed.
|
||||
void ConnectionQuota::ReleaseConnections(int num_connections) {
|
||||
if (max_incoming_connections_.load(std::memory_order_relaxed) == INT_MAX) {
|
||||
return;
|
||||
}
|
||||
GPR_ASSERT(active_incoming_connections_.fetch_sub(
|
||||
num_connections, std::memory_order_acq_rel) >=
|
||||
num_connections);
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2024 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_LIB_RESOURCE_QUOTA_CONNECTION_QUOTA_H
|
||||
#define GRPC_SRC_CORE_LIB_RESOURCE_QUOTA_CONNECTION_QUOTA_H
|
||||
|
||||
#include <grpc/support/port_platform.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
|
||||
#include "src/core/lib/gprpp/ref_counted.h"
|
||||
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
||||
#include "src/core/lib/gprpp/sync.h"
|
||||
#include "src/core/lib/resource_quota/memory_quota.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
// Tracks the amount of threads in a resource quota.
|
||||
class ConnectionQuota : public RefCounted<ConnectionQuota> {
|
||||
public:
|
||||
ConnectionQuota();
|
||||
~ConnectionQuota() override = default;
|
||||
|
||||
ConnectionQuota(const ConnectionQuota&) = delete;
|
||||
ConnectionQuota& operator=(const ConnectionQuota&) = delete;
|
||||
|
||||
// Set the maximum number of allowed incoming connections on the server.
|
||||
void SetMaxIncomingConnections(int max_incoming_connections);
|
||||
|
||||
// Returns true if the incoming connection is allowed to be accepted on the
|
||||
// server.
|
||||
bool AllowIncomingConnection(MemoryQuotaRefPtr mem_quota,
|
||||
absl::string_view peer);
|
||||
|
||||
// Mark connections as closed.
|
||||
void ReleaseConnections(int num_connections);
|
||||
|
||||
private:
|
||||
std::atomic<int> active_incoming_connections_{0};
|
||||
std::atomic<int> max_incoming_connections_{std::numeric_limits<int>::max()};
|
||||
};
|
||||
|
||||
using ConnectionQuotaRefPtr = RefCountedPtr<ConnectionQuota>;
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_RESOURCE_QUOTA_CONNECTION_QUOTA_H
|
||||
|
|
@ -658,6 +658,7 @@ CORE_SOURCE_FILES = [
|
|||
'src/core/lib/promise/trace.cc',
|
||||
'src/core/lib/resource_quota/api.cc',
|
||||
'src/core/lib/resource_quota/arena.cc',
|
||||
'src/core/lib/resource_quota/connection_quota.cc',
|
||||
'src/core/lib/resource_quota/memory_quota.cc',
|
||||
'src/core/lib/resource_quota/periodic_update.cc',
|
||||
'src/core/lib/resource_quota/resource_quota.cc',
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class EchoClientUnaryReactor : public grpc::ClientUnaryReactor {
|
|||
EchoClientUnaryReactor(ClientContext* ctx, EchoTestService::Stub* stub,
|
||||
const std::string payload, Status* status)
|
||||
: ctx_(ctx), payload_(payload), status_(status) {
|
||||
ctx_->set_wait_for_ready(true);
|
||||
request_.set_message(payload);
|
||||
stub->async()->Echo(ctx_, &request_, &response_, this);
|
||||
StartCall();
|
||||
|
|
@ -120,6 +119,7 @@ class End2EndResourceQuotaUnaryTest : public ::testing::Test {
|
|||
Status status;
|
||||
auto stub = EchoTestService::NewStub(
|
||||
CreateChannel(server_address_, grpc::InsecureChannelCredentials()));
|
||||
ctx.set_wait_for_ready(true);
|
||||
EchoClientUnaryReactor reactor(&ctx, stub.get(), payload_, &status);
|
||||
reactor.Await();
|
||||
}
|
||||
|
|
@ -145,6 +145,78 @@ class End2EndResourceQuotaUnaryTest : public ::testing::Test {
|
|||
|
||||
TEST_F(End2EndResourceQuotaUnaryTest, MultipleUnaryRPCTest) { MakeGrpcCalls(); }
|
||||
|
||||
class End2EndConnectionQuotaTest : public ::testing::TestWithParam<int> {
|
||||
protected:
|
||||
End2EndConnectionQuotaTest() {
|
||||
port_ = grpc_pick_unused_port_or_die();
|
||||
server_address_ = absl::StrCat("[::]:", port_);
|
||||
payload_ = std::string(kPayloadSizeBytes, 'a');
|
||||
ServerBuilder builder;
|
||||
builder.AddListeningPort(server_address_, InsecureServerCredentials());
|
||||
builder.AddChannelArgument(GRPC_ARG_MAX_ALLOWED_INCOMING_CONNECTIONS,
|
||||
GetParam());
|
||||
builder.AddChannelArgument(
|
||||
GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, 10000);
|
||||
builder.RegisterService(&grpc_service_);
|
||||
server_ = builder.BuildAndStart();
|
||||
}
|
||||
|
||||
~End2EndConnectionQuotaTest() override { server_->Shutdown(); }
|
||||
|
||||
std::unique_ptr<EchoTestService::Stub> CreateGrpcChannelStub() {
|
||||
grpc::ChannelArguments args;
|
||||
args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1);
|
||||
args.SetInt(GRPC_ARG_ENABLE_RETRIES, 0);
|
||||
args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, 20000);
|
||||
args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 10000);
|
||||
args.SetInt(GRPC_ARG_HTTP2_MIN_SENT_PING_INTERVAL_WITHOUT_DATA_MS, 15000);
|
||||
args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1);
|
||||
|
||||
return EchoTestService::NewStub(
|
||||
CreateCustomChannel(absl::StrCat("ipv6:[::1]:", port_),
|
||||
grpc::InsecureChannelCredentials(), args));
|
||||
}
|
||||
|
||||
void TestExceedingConnectionQuota() {
|
||||
const int kNumConnections = 2 * GetParam();
|
||||
std::vector<std::unique_ptr<EchoTestService::Stub>> stubs;
|
||||
stubs.reserve(kNumConnections);
|
||||
for (int i = 0; i < kNumConnections; i++) {
|
||||
stubs.push_back(CreateGrpcChannelStub());
|
||||
}
|
||||
for (int i = 0; i < kNumConnections; ++i) {
|
||||
ClientContext ctx;
|
||||
Status status;
|
||||
ctx.set_wait_for_ready(false);
|
||||
EchoClientUnaryReactor reactor(&ctx, stubs[i].get(), payload_, &status);
|
||||
reactor.Await();
|
||||
// The first half RPCs should succeed.
|
||||
if (i < kNumConnections / 2) {
|
||||
EXPECT_TRUE(status.ok());
|
||||
|
||||
} else {
|
||||
// The second half should fail because they would attempt to create a
|
||||
// new connection and fail since it would exceed the connection quota
|
||||
// limit set at the server.
|
||||
EXPECT_FALSE(status.ok());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int port_;
|
||||
std::unique_ptr<Server> server_;
|
||||
string server_address_;
|
||||
GrpcCallbackServiceImpl grpc_service_;
|
||||
std::string payload_;
|
||||
};
|
||||
|
||||
TEST_P(End2EndConnectionQuotaTest, ConnectionQuotaTest) {
|
||||
TestExceedingConnectionQuota();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ConnectionQuotaParamTest, End2EndConnectionQuotaTest,
|
||||
::testing::ValuesIn<int>({10, 100}));
|
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
|
|
|
|||
|
|
@ -2613,6 +2613,8 @@ src/core/lib/resource_quota/api.cc \
|
|||
src/core/lib/resource_quota/api.h \
|
||||
src/core/lib/resource_quota/arena.cc \
|
||||
src/core/lib/resource_quota/arena.h \
|
||||
src/core/lib/resource_quota/connection_quota.cc \
|
||||
src/core/lib/resource_quota/connection_quota.h \
|
||||
src/core/lib/resource_quota/memory_quota.cc \
|
||||
src/core/lib/resource_quota/memory_quota.h \
|
||||
src/core/lib/resource_quota/periodic_update.cc \
|
||||
|
|
|
|||
|
|
@ -2388,6 +2388,8 @@ src/core/lib/resource_quota/api.cc \
|
|||
src/core/lib/resource_quota/api.h \
|
||||
src/core/lib/resource_quota/arena.cc \
|
||||
src/core/lib/resource_quota/arena.h \
|
||||
src/core/lib/resource_quota/connection_quota.cc \
|
||||
src/core/lib/resource_quota/connection_quota.h \
|
||||
src/core/lib/resource_quota/memory_quota.cc \
|
||||
src/core/lib/resource_quota/memory_quota.h \
|
||||
src/core/lib/resource_quota/periodic_update.cc \
|
||||
|
|
|
|||
Loading…
Reference in New Issue