Skip to content
21 changes: 21 additions & 0 deletions source/common/runtime/runtime_protos.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@
namespace Envoy {
namespace Runtime {

// Helper class for runtime-derived uint32.
class UInt32 {
public:
UInt32(const envoy::config::core::v3::RuntimeUInt32& uint32_proto, Runtime::Loader& runtime)
: runtime_key_(uint32_proto.runtime_key()), default_value_(uint32_proto.default_value()),
runtime_(runtime) {}

const std::string& runtimeKey() const { return runtime_key_; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind adding a unit test for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.


uint32_t value() const {
uint64_t raw_value = runtime_.snapshot().getInteger(runtime_key_, default_value_);
return raw_value > std::numeric_limits<uint32_t>::max() ? default_value_

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add an error or warning log (every ~1000 times or something along those lines) for when there is an invalid value parsed that causes a revert to the default value?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may introduce additional complexity. If we introduce additional variables to record the number of invalid parsing, this class will become thread-unsafe, making it either complicated or poor in performance.
I'm not sure if there are other solutions, I look forward to your suggestions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean just put ENVOY_LOG_EVERY_POW_2() or ENVOY_LOG_EVERY_N() in a conditional instead of using that ternary operator. You don't need to get too clever here.

I would be genuinely surprised if that caused an appreciable decline in performance.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I misunderstood what you meant before (embarrassing >_<). Now I understand your suggestion and submit a new commit.

: static_cast<uint32_t>(raw_value);
}

private:
const std::string runtime_key_;
const uint32_t default_value_;
Runtime::Loader& runtime_;
};

// Helper class for runtime-derived boolean feature flags.
class FeatureFlag {
public:
Expand Down
19 changes: 19 additions & 0 deletions test/common/runtime/runtime_protos_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ class RuntimeProtosTest : public testing::Test {
NiceMock<MockLoader> runtime_;
};

TEST_F(RuntimeProtosTest, UInt32Test) {
envoy::config::core::v3::RuntimeUInt32 uint32_proto;
std::string yaml(R"EOF(
runtime_key: "foo.bar"
default_value: 99
)EOF");
TestUtility::loadFromYamlAndValidate(yaml, uint32_proto);
UInt32 test_uint32(uint32_proto, runtime_);

EXPECT_CALL(runtime_.snapshot_, getInteger("foo.bar", 99));
EXPECT_EQ(99, test_uint32.value());

EXPECT_CALL(runtime_.snapshot_, getInteger("foo.bar", 99)).WillOnce(Return(1024));
EXPECT_EQ(1024, test_uint32.value());

EXPECT_CALL(runtime_.snapshot_, getInteger("foo.bar", 99)).WillOnce(Return(1ull << 33));
EXPECT_EQ(99, test_uint32.value());
}

TEST_F(RuntimeProtosTest, PercentBasicTest) {
envoy::config::core::v3::RuntimePercent percent_proto;
std::string yaml(R"EOF(
Expand Down