When updating watches after a database switch, lookup the tenant again to get the ID on the new cluster. Update the switching test to set up tenants properly.
This commit is contained in:
parent
201eac77cf
commit
53593c77ac
|
@ -3632,6 +3632,9 @@ ACTOR Future<Version> watchValue(Database cx, Reference<const WatchParameters> p
|
|||
parameters->useProvisionalProxies,
|
||||
Reverse::False,
|
||||
parameters->version));
|
||||
if (parameters->tenant.tenantId != locationInfo.tenantEntry.id) {
|
||||
throw tenant_not_found();
|
||||
}
|
||||
|
||||
try {
|
||||
state Optional<UID> watchValueID = Optional<UID>();
|
||||
|
@ -5305,6 +5308,44 @@ Future<TenantInfo> populateAndGetTenant(Reference<TransactionState> trState, Key
|
|||
}
|
||||
}
|
||||
|
||||
// Restarts a watch after a database switch
|
||||
ACTOR Future<Void> restartWatch(Database cx,
|
||||
TenantInfo tenantInfo,
|
||||
Key key,
|
||||
Optional<Value> value,
|
||||
TagSet tags,
|
||||
SpanContext spanContext,
|
||||
TaskPriority taskID,
|
||||
Optional<UID> debugID,
|
||||
UseProvisionalProxies useProvisionalProxies) {
|
||||
// The ID of the tenant may be different on the cluster that we switched to, so obtain the new ID
|
||||
if (tenantInfo.name.present()) {
|
||||
state KeyRangeLocationInfo locationInfo = wait(getKeyLocation(cx,
|
||||
tenantInfo,
|
||||
key,
|
||||
&StorageServerInterface::watchValue,
|
||||
spanContext,
|
||||
debugID,
|
||||
useProvisionalProxies,
|
||||
Reverse::False,
|
||||
latestVersion));
|
||||
tenantInfo.tenantId = locationInfo.tenantEntry.id;
|
||||
}
|
||||
|
||||
wait(watchValueMap(cx->minAcceptableReadVersion,
|
||||
tenantInfo,
|
||||
key,
|
||||
value,
|
||||
cx,
|
||||
tags,
|
||||
spanContext,
|
||||
taskID,
|
||||
debugID,
|
||||
useProvisionalProxies));
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
// FIXME: This seems pretty horrible. Now a Database can't die until all of its watches do...
|
||||
ACTOR Future<Void> watch(Reference<Watch> watch,
|
||||
Database cx,
|
||||
|
@ -5332,16 +5373,15 @@ ACTOR Future<Void> watch(Reference<Watch> watch,
|
|||
when(wait(cx->connectionFileChanged())) {
|
||||
CODE_PROBE(true, "Recreated a watch after switch");
|
||||
cx->clearWatchMetadata();
|
||||
watch->watchFuture = watchValueMap(cx->minAcceptableReadVersion,
|
||||
tenantInfo,
|
||||
watch->key,
|
||||
watch->value,
|
||||
cx,
|
||||
tags,
|
||||
spanContext,
|
||||
taskID,
|
||||
debugID,
|
||||
useProvisionalProxies);
|
||||
watch->watchFuture = restartWatch(cx,
|
||||
tenantInfo,
|
||||
watch->key,
|
||||
watch->value,
|
||||
tags,
|
||||
spanContext,
|
||||
taskID,
|
||||
debugID,
|
||||
useProvisionalProxies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "fdbclient/ClusterConnectionMemoryRecord.h"
|
||||
#include "fdbclient/ManagementAPI.actor.h"
|
||||
#include "fdbclient/RunTransaction.actor.h"
|
||||
#include "fdbclient/TenantManagement.actor.h"
|
||||
#include "fdbrpc/simulator.h"
|
||||
#include "fdbserver/workloads/workloads.actor.h"
|
||||
#include "flow/ApiVersion.h"
|
||||
|
@ -39,9 +40,7 @@ struct DifferentClustersSameRVWorkload : TestWorkload {
|
|||
|
||||
DifferentClustersSameRVWorkload(WorkloadContext const& wcx) : TestWorkload(wcx) {
|
||||
ASSERT(g_simulator->extraDatabases.size() == 1);
|
||||
auto extraFile =
|
||||
makeReference<ClusterConnectionMemoryRecord>(ClusterConnectionString(g_simulator->extraDatabases[0]));
|
||||
extraDB = Database::createDatabase(extraFile, ApiVersion::LATEST_VERSION);
|
||||
extraDB = Database::createSimulatedExtraDatabase(g_simulator->extraDatabases[0], wcx.defaultTenant);
|
||||
testDuration = getOption(options, "testDuration"_sr, 100.0);
|
||||
switchAfter = getOption(options, "switchAfter"_sr, 50.0);
|
||||
keyToRead = getOption(options, "keyToRead"_sr, "someKey"_sr);
|
||||
|
@ -50,13 +49,27 @@ struct DifferentClustersSameRVWorkload : TestWorkload {
|
|||
|
||||
std::string description() const override { return "DifferentClustersSameRV"; }
|
||||
|
||||
Future<Void> setup(Database const& cx) override { return Void(); }
|
||||
Future<Void> setup(Database const& cx) override {
|
||||
if (clientId != 0) {
|
||||
return Void();
|
||||
}
|
||||
return _setup(cx, this);
|
||||
}
|
||||
|
||||
ACTOR static Future<Void> _setup(Database cx, DifferentClustersSameRVWorkload* self) {
|
||||
if (self->extraDB->defaultTenant.present()) {
|
||||
wait(success(TenantAPI::createTenant(self->extraDB.getReference(), self->extraDB->defaultTenant.get())));
|
||||
}
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
Future<Void> start(Database const& cx) override {
|
||||
if (clientId != 0) {
|
||||
return Void();
|
||||
}
|
||||
auto switchConnFileDb = Database::createDatabase(cx->getConnectionRecord(), -1);
|
||||
switchConnFileDb->defaultTenant = cx->defaultTenant;
|
||||
originalDB = cx;
|
||||
std::vector<Future<Void>> clients = { readerClientSeparateDBs(cx, this),
|
||||
doSwitch(switchConnFileDb, this),
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
[configuration]
|
||||
extraDatabaseMode = 'Single'
|
||||
allowDefaultTenant = false
|
||||
|
||||
[[test]]
|
||||
testTitle = 'DifferentClustersSameRV'
|
||||
|
|
Loading…
Reference in New Issue