Added simple DynamicKnobsWorkload

This commit is contained in:
sfc-gh-tclinkenbeard 2021-04-29 16:32:30 -07:00
parent 3b4932706d
commit 4d3a7ceb44
8 changed files with 123 additions and 33 deletions

View File

@ -27,34 +27,41 @@
using ConfigClassSetRef = VectorRef<KeyRef>;
using ConfigClassSet = Standalone<ConfigClassSetRef>;
class ConfigUpdateKeyRef {
KeyRef configClass;
KeyRef knobName;
struct ConfigUpdateKeyRef {
KeyRef configClass;
KeyRef knobName;
ConfigUpdateKeyRef()=default;
explicit ConfigUpdateKeyRef(Arena &arena, KeyRef configClass, KeyRef knobName)
: configClass(arena, configClass), knobName(arena, knobName) {}
ConfigUpdateKeyRef() = default;
ConfigUpdateKeyRef(Arena& arena, KeyRef configClass, KeyRef knobName)
: configClass(arena, configClass), knobName(arena, knobName) {}
ConfigUpdateKeyRef(Arena& arena, ConfigUpdateKeyRef const& rhs)
: ConfigUpdateKeyRef(arena, rhs.configClass, rhs.knobName) {}
template<class Ar>
void serialize(Ar &ar) {
serializer(ar, configClass, knobName);
}
template <class Ar>
void serialize(Ar& ar) {
serializer(ar, configClass, knobName);
}
size_t expectedSize() const { return configClass.expectedSize() + knobName.expectedSize(); }
};
using ConfigUpdateKey = Standalone<ConfigUpdateKeyRef>;
class ConfigUpdateValueRef {
KeyRef description;
ValueRef value;
double timestamp;
public:
struct ConfigUpdateValueRef {
KeyRef description;
ValueRef value;
double timestamp;
ConfigUpdateValueRef()=default;
explicit ConfigUpdateValueRef(Arena &arena, KeyRef description, ValueRef value, double timestamp)
: description(arena, description), value(arena, value), timestamp(timestamp) {}
ConfigUpdateValueRef() = default;
ConfigUpdateValueRef(Arena& arena, KeyRef description, ValueRef value, double timestamp)
: description(arena, description), value(arena, value), timestamp(timestamp) {}
ConfigUpdateValueRef(Arena& arena, ConfigUpdateValueRef const& rhs)
: ConfigUpdateValueRef(arena, rhs.description, rhs.value, rhs.timestamp) {}
template<class Ar>
void serialize(Ar &ar) {
serializer(ar, description, value, timestamp);
}
template <class Ar>
void serialize(Ar& ar) {
serializer(ar, description, value, timestamp);
}
size_t expectedSize() const { return description.expectedSize() + value.expectedSize() + sizeof(double); }
};
using ConfigUpdateValue = Standalone<ConfigUpdateValueRef>;

View File

@ -161,6 +161,7 @@ set(FDBSERVER_SRCS
workloads/DiskDurabilityTest.actor.cpp
workloads/Downgrade.actor.cpp
workloads/DummyWorkload.actor.cpp
workloads/DynamicKnobs.actor.cpp
workloads/ExternalWorkload.actor.cpp
workloads/FastTriggeredWatches.actor.cpp
workloads/FileSystem.actor.cpp

View File

@ -38,7 +38,6 @@ class LocalConfigurationImpl {
TestKnobs knobs;
std::map<Key, Value> manuallyOverriddenKnobs;
std::map<Key, Value> configDatabaseOverriddenKnobs;
TestKnobs defaultKnobs;
ACTOR static Future<Void> saveConfigClasses(LocalConfigurationImpl* self) {
self->kvStore->set(KeyValueRef(configClassesKey, BinaryWriter::toValue(self->configClasses, IncludeVersion())));
@ -66,7 +65,6 @@ class LocalConfigurationImpl {
}
ACTOR static Future<Void> init(LocalConfigurationImpl* self) {
self->defaultKnobs.initialize();
wait(self->kvStore->init());
wait(getLastSeenVersion(self));
state Optional<Value> storedConfigClassesValue = wait(self->kvStore->readValue(configClassesKey));
@ -85,14 +83,14 @@ class LocalConfigurationImpl {
}
Standalone<RangeResultRef> range = wait(self->kvStore->readRange(knobOverrideKeys));
for (const auto &kv : range) {
self->configDatabaseOverriddenKnobs[kv.key] = kv.value;
self->configDatabaseOverriddenKnobs[kv.key.removePrefix(knobOverrideKeys.begin)] = kv.value;
}
self->updateInMemoryKnobs();
return Void();
}
void updateInMemoryKnobs() {
knobs = defaultKnobs;
knobs.reset();
for (const auto& [knobName, knobValue] : configDatabaseOverriddenKnobs) {
// TODO: Fail gracefully
ASSERT(knobs.setKnob(knobName.toString(), knobValue.toString()));
@ -108,8 +106,10 @@ class LocalConfigurationImpl {
ACTOR static Future<Void> applyKnobUpdates(LocalConfigurationImpl *self, ConfigFollowerGetFullDatabaseReply reply) {
self->kvStore->clear(knobOverrideKeys);
for (const auto &[k, v] : reply.database) {
self->kvStore->set(KeyValueRef(k.withPrefix(knobOverrideKeys.begin), v));
self->configDatabaseOverriddenKnobs[k] = v;
Key knobName = BinaryReader::fromStringRef<ConfigUpdateKey>(k, IncludeVersion()).knobName;
Value knobValue = BinaryReader::fromStringRef<ConfigUpdateValue>(v, IncludeVersion()).value;
self->kvStore->set(KeyValueRef(knobName.withPrefix(knobOverrideKeys.begin), knobValue));
self->configDatabaseOverriddenKnobs[knobName] = knobValue;
}
self->kvStore->set(KeyValueRef(lastSeenVersionKey, BinaryWriter::toValue(self->lastSeenVersion, IncludeVersion())));
wait(self->kvStore->commit());
@ -121,13 +121,21 @@ class LocalConfigurationImpl {
for (const auto &versionedMutation : reply.versionedMutations) {
const auto &mutation = versionedMutation.mutation;
if (mutation.type == MutationRef::SetValue) {
self->kvStore->set(KeyValueRef(mutation.param1.withPrefix(knobOverrideKeys.begin), mutation.param2));
self->configDatabaseOverriddenKnobs[mutation.param1] = mutation.param2;
Key knobName = BinaryReader::fromStringRef<ConfigUpdateKey>(mutation.param1, IncludeVersion()).knobName;
Value knobValue =
BinaryReader::fromStringRef<ConfigUpdateValue>(mutation.param2, IncludeVersion()).value;
self->kvStore->set(KeyValueRef(knobName.withPrefix(knobOverrideKeys.begin), knobValue));
self->configDatabaseOverriddenKnobs[knobName] = knobValue;
} else if (mutation.type == MutationRef::ClearRange) {
self->kvStore->clear(KeyRangeRef(mutation.param1.withPrefix(knobOverrideKeys.begin), mutation.param2.withPrefix(knobOverrideKeys.begin)));
Key beginKnobName =
BinaryReader::fromStringRef<ConfigUpdateKey>(mutation.param1, IncludeVersion()).knobName;
Key endKnobName =
BinaryReader::fromStringRef<ConfigUpdateKey>(mutation.param2, IncludeVersion()).knobName;
self->kvStore->clear(KeyRangeRef(beginKnobName.withPrefix(knobOverrideKeys.begin),
endKnobName.withPrefix(knobOverrideKeys.begin)));
self->configDatabaseOverriddenKnobs.erase(
self->configDatabaseOverriddenKnobs.lower_bound(mutation.param1),
self->configDatabaseOverriddenKnobs.lower_bound(mutation.param2));
self->configDatabaseOverriddenKnobs.lower_bound(beginKnobName),
self->configDatabaseOverriddenKnobs.lower_bound(endKnobName));
} else {
ASSERT(false);
}
@ -233,3 +241,8 @@ Future<Void> LocalConfiguration::consume(Reference<AsyncVar<ServerDBInfo> const>
void TestKnobs::initialize() {
init(TEST, 0);
}
void TestKnobs::reset() {
explicitlySetKnobs.clear();
initialize();
}

View File

@ -32,6 +32,7 @@ class TestKnobs : public Knobs {
public:
int64_t TEST;
void initialize();
void reset();
};
class LocalConfiguration {

View File

@ -0,0 +1,60 @@
/*
* Cycle.actor.cpp
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2018 Apple Inc. and the FoundationDB project 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 "fdbclient/ConfigKnobs.h"
#include "fdbclient/IConfigTransaction.h"
#include "fdbserver/workloads/workloads.actor.h"
#include "flow/actorcompiler.h" // This must be the last #include
const Key testConfigClass = "testConfigClass"_sr;
const Key testKnobName = "test"_sr;
const Key testKnobValue = "5"_sr;
const Key testUpdateDescription = "test knob update"_sr;
class DynamicKnobsWorkload : public TestWorkload {
ACTOR static Future<Void> start(DynamicKnobsWorkload* self, Database cx) {
state Arena arena;
state Reference<IConfigTransaction> tr =
makeReference<SimpleConfigTransaction>(cx->getConnectionFile()->getConnectionString());
loop {
try {
ConfigUpdateKey key = ConfigUpdateKeyRef(arena, testConfigClass, testKnobName);
ConfigUpdateValue value = ConfigUpdateValueRef(arena, testUpdateDescription, testKnobValue, now());
tr->set(BinaryWriter::toValue(key, IncludeVersion()), BinaryWriter::toValue(value, IncludeVersion()));
wait(tr->commit());
return Void();
} catch (Error& e) {
wait(tr->onError(e));
}
}
}
public:
DynamicKnobsWorkload(WorkloadContext const& wcx) : TestWorkload(wcx) {}
std::string description() const override { return "DynamicKnobs"; }
Future<Void> setup(Database const& cx) override { return Void(); }
Future<Void> start(Database const& cx) override { return start(this, cx); }
Future<bool> check(Database const& cx) override { return true; }
void getMetrics(std::vector<PerfMetric>& m) override {}
};
WorkloadFactory<DynamicKnobsWorkload> DynamicKnobsWorkloadFactory("DynamicKnobs");

View File

@ -37,6 +37,8 @@ public:
protected:
Knobs() = default;
Knobs(Knobs const&) = delete;
Knobs& operator=(Knobs const&) = delete;
void initKnob(double& knob, double value, std::string const& name);
void initKnob(int64_t& knob, int64_t value, std::string const& name);
void initKnob(int& knob, int value, std::string const& name);

View File

@ -160,6 +160,7 @@ if(WITH_PYTHON)
add_fdb_test(TEST_FILES rare/CycleRollbackClogged.toml)
add_fdb_test(TEST_FILES rare/CycleWithKills.toml)
add_fdb_test(TEST_FILES rare/Downgrade.toml)
add_fdb_test(TEST_FILES rare/DynamicKnobs.toml)
add_fdb_test(TEST_FILES rare/FuzzTest.toml)
add_fdb_test(TEST_FILES rare/InventoryTestHeavyWrites.toml)
add_fdb_test(TEST_FILES rare/LargeApiCorrectness.toml)

View File

@ -0,0 +1,5 @@
[[test]]
testTitle='DynamicKnobs'
[[test.workload]]
testName='DynamicKnobs'