-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
admission control: Implement thread-local controller (#11628)
Signed-off-by: Tony Allen <tony@allen.gg>
- Loading branch information
Showing
15 changed files
with
594 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
source/extensions/filters/http/admission_control/config.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#include "extensions/filters/http/admission_control/config.h" | ||
|
||
#include "envoy/extensions/filters/http/admission_control/v3alpha/admission_control.pb.h" | ||
#include "envoy/extensions/filters/http/admission_control/v3alpha/admission_control.pb.validate.h" | ||
#include "envoy/registry/registry.h" | ||
|
||
#include "common/common/enum_to_int.h" | ||
|
||
#include "extensions/filters/http/admission_control/admission_control.h" | ||
#include "extensions/filters/http/admission_control/evaluators/response_evaluator.h" | ||
#include "extensions/filters/http/admission_control/evaluators/success_criteria_evaluator.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace AdmissionControl { | ||
|
||
static constexpr std::chrono::seconds defaultSamplingWindow{120}; | ||
|
||
Http::FilterFactoryCb AdmissionControlFilterFactory::createFilterFactoryFromProtoTyped( | ||
const envoy::extensions::filters::http::admission_control::v3alpha::AdmissionControl& config, | ||
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) { | ||
|
||
const std::string prefix = stats_prefix + "admission_control."; | ||
|
||
// Create the thread-local controller. | ||
auto tls = context.threadLocal().allocateSlot(); | ||
auto sampling_window = std::chrono::seconds( | ||
PROTOBUF_GET_MS_OR_DEFAULT(config, sampling_window, 1000 * defaultSamplingWindow.count()) / | ||
1000); | ||
tls->set( | ||
[sampling_window, &context](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { | ||
return std::make_shared<ThreadLocalControllerImpl>(context.timeSource(), sampling_window); | ||
}); | ||
|
||
std::unique_ptr<ResponseEvaluator> response_evaluator; | ||
switch (config.evaluation_criteria_case()) { | ||
case AdmissionControlProto::EvaluationCriteriaCase::kSuccessCriteria: | ||
response_evaluator = std::make_unique<SuccessCriteriaEvaluator>(config.success_criteria()); | ||
break; | ||
case AdmissionControlProto::EvaluationCriteriaCase::EVALUATION_CRITERIA_NOT_SET: | ||
NOT_REACHED_GCOVR_EXCL_LINE; | ||
} | ||
|
||
AdmissionControlFilterConfigSharedPtr filter_config = | ||
std::make_shared<AdmissionControlFilterConfig>(config, context.runtime(), context.random(), | ||
context.scope(), std::move(tls), | ||
std::move(response_evaluator)); | ||
|
||
return [filter_config, prefix](Http::FilterChainFactoryCallbacks& callbacks) -> void { | ||
callbacks.addStreamFilter(std::make_shared<AdmissionControlFilter>(filter_config, prefix)); | ||
}; | ||
} | ||
|
||
/** | ||
* Static registration for the admission_control filter. @see RegisterFactory. | ||
*/ | ||
REGISTER_FACTORY(AdmissionControlFilterFactory, | ||
Server::Configuration::NamedHttpFilterConfigFactory); | ||
|
||
} // namespace AdmissionControl | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
|
||
#include "envoy/extensions/filters/http/admission_control/v3alpha/admission_control.pb.h" | ||
#include "envoy/extensions/filters/http/admission_control/v3alpha/admission_control.pb.validate.h" | ||
|
||
#include "extensions/filters/http/common/factory_base.h" | ||
#include "extensions/filters/http/well_known_names.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace AdmissionControl { | ||
|
||
/** | ||
* Config registration for the adaptive concurrency limit filter. @see NamedHttpFilterConfigFactory. | ||
*/ | ||
class AdmissionControlFilterFactory | ||
: public Common::FactoryBase< | ||
envoy::extensions::filters::http::admission_control::v3alpha::AdmissionControl> { | ||
public: | ||
AdmissionControlFilterFactory() : FactoryBase(HttpFilterNames::get().AdmissionControl) {} | ||
|
||
Http::FilterFactoryCb createFilterFactoryFromProtoTyped( | ||
const envoy::extensions::filters::http::admission_control::v3alpha::AdmissionControl& | ||
proto_config, | ||
const std::string& stats_prefix, Server::Configuration::FactoryContext& context) override; | ||
}; | ||
|
||
} // namespace AdmissionControl | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
49 changes: 49 additions & 0 deletions
49
source/extensions/filters/http/admission_control/thread_local_controller.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include "extensions/filters/http/admission_control/thread_local_controller.h" | ||
|
||
#include <cstdint> | ||
|
||
#include "envoy/common/pure.h" | ||
#include "envoy/common/time.h" | ||
#include "envoy/http/codes.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace AdmissionControl { | ||
|
||
static constexpr std::chrono::seconds defaultHistoryGranularity{1}; | ||
|
||
ThreadLocalControllerImpl::ThreadLocalControllerImpl(TimeSource& time_source, | ||
std::chrono::seconds sampling_window) | ||
: time_source_(time_source), sampling_window_(sampling_window) {} | ||
|
||
void ThreadLocalControllerImpl::maybeUpdateHistoricalData() { | ||
// Purge stale samples. | ||
while (!historical_data_.empty() && ageOfOldestSample() >= sampling_window_) { | ||
removeOldestSample(); | ||
} | ||
|
||
// It's possible we purged stale samples from the history and are left with nothing, so it's | ||
// necessary to add an empty entry. We will also need to roll over into a new entry in the | ||
// historical data if we've exceeded the time specified by the granularity. | ||
if (historical_data_.empty() || ageOfNewestSample() >= defaultHistoryGranularity) { | ||
historical_data_.emplace_back(time_source_.monotonicTime(), RequestData()); | ||
} | ||
} | ||
|
||
void ThreadLocalControllerImpl::recordRequest(bool success) { | ||
maybeUpdateHistoricalData(); | ||
|
||
// The back of the deque will be the most recent samples. | ||
++historical_data_.back().second.requests; | ||
++global_data_.requests; | ||
if (success) { | ||
++historical_data_.back().second.successes; | ||
++global_data_.successes; | ||
} | ||
} | ||
|
||
} // namespace AdmissionControl | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.