-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Overload] Active downstream connections resource monitor #19186
Changes from all commits
7dc2ca5
3020230
7ee2b48
77ee91c
0ed8742
f6ed8e3
8acddb5
0b505fa
6ac675f
0752313
0e9f4df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. | ||
|
||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
api_proto_package( | ||
deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.extensions.resource_monitors.downstream_connections.v3; | ||
|
||
import "udpa/annotations/status.proto"; | ||
import "validate/validate.proto"; | ||
|
||
option java_package = "io.envoyproxy.envoy.extensions.resource_monitors.downstream_connections.v3"; | ||
option java_outer_classname = "DownstreamConnectionsProto"; | ||
option java_multiple_files = true; | ||
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/resource_monitors/downstream_connections/v3;downstream_connectionsv3"; | ||
option (udpa.annotations.file_status).package_version_status = ACTIVE; | ||
|
||
// [#protodoc-title: Downstream connections] | ||
// [#extension: envoy.resource_monitors.downstream_connections] | ||
|
||
// The downstream connections resource monitor tracks the global number of open downstream connections. | ||
// [#not-implemented-hide:] | ||
message DownstreamConnectionsConfig { | ||
// Maximum threshold for global open active downstream connections, defaults to 0. | ||
// If monitor is configured via Overload manager api and has no value set, Envoy will reject all incoming connections. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically with the gt annotation that you added Envoy will reject the configuration as your test https://github.com/envoyproxy/envoy/pull/19186/files#diff-1fdfe762c6263d74ffc5365cd93a44ff14c64adac898bbf1e2de53a3a91e000bR61 shows. Is this expected to be >= 0 or > 0?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is up for discussion. Having it '>0' would require users to explicitly configure threshold for monitor (and fail/error on startup otherwise if threshold is not configured). While '>=0' can be more tricky for users, if they forget to configure the threshold, monitor will use default value 0 and reject all incoming connections. First option (require explicit value > 0) is cleaner in my opinion, although monitor will not be able to reject all incoming connections. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sgtm |
||
int64 max_active_downstream_connections = 1 [(validate.rules).int64 = {gt: 0}]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_cc_extension", | ||
"envoy_cc_library", | ||
"envoy_extension_package", | ||
) | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
envoy_extension_package() | ||
|
||
envoy_cc_library( | ||
name = "downstream_connections_monitor", | ||
srcs = ["downstream_connections_monitor.cc"], | ||
hdrs = ["downstream_connections_monitor.h"], | ||
deps = [ | ||
"//envoy/server:proactive_resource_monitor_interface", | ||
"//envoy/server:resource_monitor_config_interface", | ||
"//source/common/common:assert_lib", | ||
"@envoy_api//envoy/extensions/resource_monitors/downstream_connections/v3:pkg_cc_proto", | ||
], | ||
) | ||
|
||
envoy_cc_extension( | ||
name = "config", | ||
srcs = ["config.cc"], | ||
hdrs = ["config.h"], | ||
deps = [ | ||
":downstream_connections_monitor", | ||
"//envoy/registry", | ||
"//source/common/common:assert_lib", | ||
"//source/extensions/resource_monitors/common:factory_base_lib", | ||
"@envoy_api//envoy/extensions/resource_monitors/downstream_connections/v3:pkg_cc_proto", | ||
], | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "source/extensions/resource_monitors/downstream_connections/config.h" | ||
|
||
#include "envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.pb.h" | ||
#include "envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.pb.validate.h" | ||
#include "envoy/registry/registry.h" | ||
|
||
#include "source/common/protobuf/utility.h" | ||
#include "source/extensions/resource_monitors/downstream_connections/downstream_connections_monitor.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace ResourceMonitors { | ||
namespace DownstreamConnections { | ||
|
||
Server::ProactiveResourceMonitorPtr | ||
ActiveDownstreamConnectionsMonitorFactory::createProactiveResourceMonitorFromProtoTyped( | ||
const envoy::extensions::resource_monitors::downstream_connections::v3:: | ||
DownstreamConnectionsConfig& config, | ||
Server::Configuration::ResourceMonitorFactoryContext& /*unused_context*/) { | ||
return std::make_unique<ActiveDownstreamConnectionsResourceMonitor>(config); | ||
} | ||
|
||
/** | ||
* Static registration for the downstream connections resource monitor factory. @see | ||
* RegistryFactory. | ||
*/ | ||
REGISTER_FACTORY(ActiveDownstreamConnectionsMonitorFactory, | ||
Server::Configuration::ProactiveResourceMonitorFactory); | ||
|
||
} // namespace DownstreamConnections | ||
} // namespace ResourceMonitors | ||
} // namespace Extensions | ||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
|
||
#include "envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.pb.h" | ||
#include "envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.pb.validate.h" | ||
#include "envoy/server/resource_monitor_config.h" | ||
|
||
#include "source/extensions/resource_monitors/common/factory_base.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace ResourceMonitors { | ||
namespace DownstreamConnections { | ||
|
||
class ActiveDownstreamConnectionsMonitorFactory | ||
: public Common::ProactiveFactoryBase< | ||
envoy::extensions::resource_monitors::downstream_connections::v3:: | ||
DownstreamConnectionsConfig> { | ||
public: | ||
ActiveDownstreamConnectionsMonitorFactory() | ||
: ProactiveFactoryBase("envoy.resource_monitors.downstream_connections") {} | ||
|
||
private: | ||
Server::ProactiveResourceMonitorPtr createProactiveResourceMonitorFromProtoTyped( | ||
const envoy::extensions::resource_monitors::downstream_connections::v3:: | ||
DownstreamConnectionsConfig& config, | ||
Server::Configuration::ResourceMonitorFactoryContext& context) override; | ||
}; | ||
|
||
} // namespace DownstreamConnections | ||
} // namespace ResourceMonitors | ||
} // namespace Extensions | ||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "source/extensions/resource_monitors/downstream_connections/downstream_connections_monitor.h" | ||
|
||
#include "envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.pb.h" | ||
|
||
#include "source/common/common/assert.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace ResourceMonitors { | ||
namespace DownstreamConnections { | ||
|
||
ActiveDownstreamConnectionsResourceMonitor::ActiveDownstreamConnectionsResourceMonitor( | ||
const envoy::extensions::resource_monitors::downstream_connections::v3:: | ||
DownstreamConnectionsConfig& config) | ||
: max_(config.max_active_downstream_connections()), current_(0){}; | ||
|
||
bool ActiveDownstreamConnectionsResourceMonitor::tryAllocateResource(int64_t increment) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In real use cases can tryAllocateResources and tryDeallocateResources be called concurrently? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, they can be called for example from multiple worker threads There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do think using RAII for the resource allocated / decremented is probably the way to go to stop incorrect from being possible and leaking resources. For example if max = 15, and originally we have
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Realised that RAII/Memento approach will not work with cross thread visibility. Various threads will be accessing tryAlloc/deAlloc resource via their thread local overload state object. The point of using atomic counter was to bypass periodic slow flushes/updates in OM (where thread local overload state is periodically updated for all threads) and instead perform faster checks from any thread relying on atomic guarantees for cross thread visibility of latest counter value. |
||
int64_t new_val = (current_ += increment); | ||
if (new_val > max_ || new_val < 0) { | ||
current_ -= increment; | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool ActiveDownstreamConnectionsResourceMonitor::tryDeallocateResource(int64_t decrement) { | ||
RELEASE_ASSERT(decrement <= current_, | ||
"Cannot deallocate resource, current resource usage is lower than decrement"); | ||
int64_t new_val = (current_ -= decrement); | ||
if (new_val < 0) { | ||
current_ += decrement; | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
int64_t ActiveDownstreamConnectionsResourceMonitor::currentResourceUsage() const { | ||
return current_.load(); | ||
} | ||
int64_t ActiveDownstreamConnectionsResourceMonitor::maxResourceUsage() const { return max_; }; | ||
|
||
} // namespace DownstreamConnections | ||
} // namespace ResourceMonitors | ||
} // namespace Extensions | ||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#pragma once | ||
|
||
#include "envoy/extensions/resource_monitors/downstream_connections/v3/downstream_connections.pb.h" | ||
#include "envoy/server/proactive_resource_monitor.h" | ||
|
||
#include "source/common/common/assert.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace ResourceMonitors { | ||
namespace DownstreamConnections { | ||
|
||
class ActiveDownstreamConnectionsResourceMonitor : public Server::ProactiveResourceMonitor { | ||
public: | ||
ActiveDownstreamConnectionsResourceMonitor( | ||
const envoy::extensions::resource_monitors::downstream_connections::v3:: | ||
DownstreamConnectionsConfig& config); | ||
|
||
bool tryAllocateResource(int64_t increment) override; | ||
|
||
bool tryDeallocateResource(int64_t decrement) override; | ||
|
||
int64_t currentResourceUsage() const override; | ||
int64_t maxResourceUsage() const override; | ||
|
||
protected: | ||
int64_t max_; | ||
std::atomic<int64_t> current_; | ||
}; | ||
|
||
} // namespace DownstreamConnections | ||
} // namespace ResourceMonitors | ||
} // namespace Extensions | ||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_package", | ||
) | ||
load( | ||
"//test/extensions:extensions_build_system.bzl", | ||
"envoy_extension_cc_test", | ||
) | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
envoy_package() | ||
|
||
envoy_extension_cc_test( | ||
name = "downstream_connections_monitor_test", | ||
srcs = ["downstream_connections_monitor_test.cc"], | ||
extension_names = ["envoy.resource_monitors.downstream_connections"], | ||
external_deps = ["abseil_optional"], | ||
deps = [ | ||
"//source/extensions/resource_monitors/downstream_connections:downstream_connections_monitor", | ||
"@envoy_api//envoy/extensions/resource_monitors/downstream_connections/v3:pkg_cc_proto", | ||
], | ||
) | ||
|
||
envoy_extension_cc_test( | ||
name = "config_test", | ||
srcs = ["config_test.cc"], | ||
extension_names = ["envoy.resource_monitors.downstream_connections"], | ||
deps = [ | ||
"//envoy/registry", | ||
"//source/extensions/resource_monitors/downstream_connections:config", | ||
"//source/server:resource_monitor_config_lib", | ||
"//test/mocks/event:event_mocks", | ||
"//test/mocks/server:options_mocks", | ||
"//test/test_common:utility_lib", | ||
"@envoy_api//envoy/extensions/resource_monitors/downstream_connections/v3:pkg_cc_proto", | ||
], | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be an v3alpha if this is an alpha extension? seems like it is from https://github.com/envoyproxy/envoy/pull/19186/files#diff-5fb7b50b079c821a11f230bec1d1ab9b05256541f14f8bc5045941d301759801
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like is not possible to specify any other version for extension than
v3
according to api style guide for extensions. I've marked entire proto file for this extension as work in progress and hid it from the docs (until the third PR lands in that would make use of this new monitor in tcp listener)