Added simple DynamicKnobsWorkload
This commit is contained in:
parent
3b4932706d
commit
4d3a7ceb44
|
@ -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>;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ class TestKnobs : public Knobs {
|
|||
public:
|
||||
int64_t TEST;
|
||||
void initialize();
|
||||
void reset();
|
||||
};
|
||||
|
||||
class LocalConfiguration {
|
||||
|
|
|
@ -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");
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[[test]]
|
||||
testTitle='DynamicKnobs'
|
||||
|
||||
[[test.workload]]
|
||||
testName='DynamicKnobs'
|
Loading…
Reference in New Issue