Serve no-op configuration database interface when disabled
By continuing to serve the configuration database interface used by clients even when disabled, clients no longer need to specify a special `--no-config-db` option when running commands which talk to the configuration database.
This commit is contained in:
parent
462c164bbd
commit
890e7610ad
|
@ -175,10 +175,15 @@ for *every* ``fdbserver`` process.
|
|||
The only client change from the configuration database is as part of the change
|
||||
coordinators command. The change coordinators command is not considered
|
||||
successful until the configuration database is readable on the new
|
||||
coordinators. This will cause the change coordinators command to hang if run
|
||||
against a database with dynamic knobs disabled. To disable the client side
|
||||
configuration database liveness check, specify the ``--no-config-db`` flag when
|
||||
changing coordinators. For example:
|
||||
coordinators. If the configuration database has been disabled server-side via
|
||||
the ``-no-config-db`` command line option, the coordinators will continue to
|
||||
serve the configuration interface, but will reply to each request with an empty
|
||||
response. Client-side changes are no longer necessary when disabling the
|
||||
configuration database.
|
||||
|
||||
Optionally, the client liveness check of the configuration database can be
|
||||
prevented by specifying the ``-no-config-db`` flag when changing the
|
||||
coordinators. For example:
|
||||
|
||||
```
|
||||
fdbcli> coordinators auto --no-config-db
|
||||
|
|
|
@ -821,6 +821,33 @@ class ConfigNodeImpl {
|
|||
return Void();
|
||||
}
|
||||
|
||||
ACTOR static Future<Void> serveDisabled(ConfigNodeImpl* self,
|
||||
ConfigTransactionInterface const* cti,
|
||||
ConfigFollowerInterface const* cfi) {
|
||||
loop {
|
||||
choose {
|
||||
when(ConfigTransactionGetGenerationRequest req = waitNext(cti->getGeneration.getFuture())) {
|
||||
req.reply.send(ConfigTransactionGetGenerationReply{ ConfigGeneration() });
|
||||
}
|
||||
when(ConfigTransactionGetRequest req = waitNext(cti->get.getFuture())) {
|
||||
req.reply.send(ConfigTransactionGetReply());
|
||||
}
|
||||
when(ConfigTransactionCommitRequest req = waitNext(cti->commit.getFuture())) {
|
||||
req.reply.send(Void());
|
||||
}
|
||||
when(ConfigTransactionGetConfigClassesRequest req = waitNext(cti->getClasses.getFuture())) {
|
||||
req.reply.send(ConfigTransactionGetConfigClassesReply());
|
||||
}
|
||||
when(ConfigTransactionGetKnobsRequest req = waitNext(cti->getKnobs.getFuture())) {
|
||||
req.reply.send(ConfigTransactionGetKnobsReply());
|
||||
}
|
||||
when(state ConfigFollowerLockRequest req = waitNext(cfi->lock.getFuture())) {
|
||||
req.reply.send(Void());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ACTOR static Future<bool> registered(ConfigNodeImpl* self) {
|
||||
Optional<Value> value = wait(self->kvStore->readValue(registeredKey));
|
||||
return value.present();
|
||||
|
@ -846,6 +873,10 @@ public:
|
|||
return serve(this, &cbi, &cti, &cfi);
|
||||
}
|
||||
|
||||
Future<Void> serveDisabled(ConfigTransactionInterface const& cti, ConfigFollowerInterface const& cfi) {
|
||||
return serveDisabled(this, &cti, &cfi);
|
||||
}
|
||||
|
||||
Future<Void> serve(ConfigBroadcastInterface const& cbi) { return serve(this, &cbi, true); }
|
||||
|
||||
Future<Void> serve(ConfigTransactionInterface const& cti) { return serve(this, &cti); }
|
||||
|
@ -869,6 +900,10 @@ Future<Void> ConfigNode::serve(ConfigBroadcastInterface const& cbi,
|
|||
return impl->serve(cbi, cti, cfi);
|
||||
}
|
||||
|
||||
Future<Void> ConfigNode::serveDisabled(ConfigTransactionInterface const& cti, ConfigFollowerInterface const& cfi) {
|
||||
return impl->serveDisabled(cti, cfi);
|
||||
}
|
||||
|
||||
Future<Void> ConfigNode::serve(ConfigBroadcastInterface const& cbi) {
|
||||
return impl->serve(cbi);
|
||||
}
|
||||
|
|
|
@ -773,11 +773,21 @@ ACTOR Future<Void> coordinationServer(std::string dataFolder,
|
|||
.detail("Folder", dataFolder)
|
||||
.detail("ConfigNodeValid", configNode.isValid());
|
||||
|
||||
if (configNode.isValid()) {
|
||||
configTransactionInterface.setupWellKnownEndpoints();
|
||||
configFollowerInterface.setupWellKnownEndpoints();
|
||||
// Serve some of the config node interface even if it is disabled. This
|
||||
// allows clients to get responses to requests and avoid hanging when
|
||||
// running commands such as a coordinator change.
|
||||
bool configNodeValid = configNode.isValid();
|
||||
if (!configNodeValid) {
|
||||
configNode = makeReference<ConfigNode>(dataFolder);
|
||||
}
|
||||
configTransactionInterface.setupWellKnownEndpoints();
|
||||
configFollowerInterface.setupWellKnownEndpoints();
|
||||
if (configNodeValid) {
|
||||
configDatabaseServer =
|
||||
brokenPromiseToNever(configNode->serve(cbi, configTransactionInterface, configFollowerInterface));
|
||||
} else {
|
||||
configDatabaseServer =
|
||||
brokenPromiseToNever(configNode->serveDisabled(configTransactionInterface, configFollowerInterface));
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -37,6 +37,9 @@ public:
|
|||
Future<Void> serve(ConfigBroadcastInterface const&,
|
||||
ConfigTransactionInterface const&,
|
||||
ConfigFollowerInterface const&);
|
||||
// Serves some interfaces even when the configuration database is disabled,
|
||||
// to prevent client requests from hanging.
|
||||
Future<Void> serveDisabled(ConfigTransactionInterface const&, ConfigFollowerInterface const&);
|
||||
|
||||
public: // Testing
|
||||
Future<Void> serve(ConfigBroadcastInterface const&);
|
||||
|
|
Loading…
Reference in New Issue