MVC2.0: Notifying clients about deleting or disabling client libraries that have upload or active status;
Declare library status access and change transactions as lock aware
This commit is contained in:
parent
31386c0f03
commit
418cc4dc50
|
@ -133,9 +133,11 @@ bool isAvailableForDownload(ClientLibStatus status) {
|
|||
status == ClientLibStatus::ACTIVE;
|
||||
}
|
||||
|
||||
void updateClientLibChangeCounter(Transaction& tr, ClientLibStatus status) {
|
||||
void updateClientLibChangeCounter(Transaction& tr, ClientLibStatus prevStatus, ClientLibStatus newStatus) {
|
||||
static const int64_t counterIncVal = 1;
|
||||
if (status == ClientLibStatus::DOWNLOAD || status == ClientLibStatus::ACTIVE) {
|
||||
if ((prevStatus != newStatus) &&
|
||||
(newStatus == ClientLibStatus::DOWNLOAD || newStatus == ClientLibStatus::ACTIVE ||
|
||||
prevStatus == ClientLibStatus::DOWNLOAD || prevStatus == ClientLibStatus::ACTIVE)) {
|
||||
tr.atomicOp(clientLibChangeCounterKey,
|
||||
StringRef(reinterpret_cast<const uint8_t*>(&counterIncVal), sizeof(counterIncVal)),
|
||||
MutationRef::AddValue);
|
||||
|
@ -448,7 +450,7 @@ ACTOR Future<Void> uploadClientLibrary(Database db,
|
|||
tr.setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
|
||||
tr.setOption(FDBTransactionOptions::LOCK_AWARE);
|
||||
tr.set(clientLibMetaKey, ValueRef(jsStr));
|
||||
updateClientLibChangeCounter(tr, targetStatus);
|
||||
updateClientLibChangeCounter(tr, ClientLibStatus::DISABLED, targetStatus);
|
||||
wait(tr.commit());
|
||||
break;
|
||||
} catch (Error& e) {
|
||||
|
@ -505,7 +507,7 @@ ACTOR Future<Void> downloadClientLibrary(Database db,
|
|||
}
|
||||
}
|
||||
|
||||
// Allow downloading only libraries in the available state
|
||||
// Prevent downloading not yet uploaded and disabled libraries
|
||||
if (!isAvailableForDownload(getStatusByName(getMetadataStrAttr(metadataJson, CLIENTLIB_ATTR_STATUS)))) {
|
||||
throw client_lib_not_available();
|
||||
}
|
||||
|
@ -637,8 +639,11 @@ ACTOR Future<Void> deleteClientLibrary(Database db, Standalone<StringRef> client
|
|||
TraceEvent(SevWarnAlways, "ClientLibraryNotFound").detail("Key", clientLibMetaKey);
|
||||
throw client_lib_not_found();
|
||||
}
|
||||
json_spirit::mObject metadataJson = parseMetadataJson(metadataOpt.get());
|
||||
ClientLibStatus status = getStatusByName(getMetadataStrAttr(metadataJson, CLIENTLIB_ATTR_STATUS));
|
||||
tr.clear(prefixRange(chunkKeyPrefix));
|
||||
tr.clear(clientLibMetaKey);
|
||||
updateClientLibChangeCounter(tr, status, ClientLibStatus::DISABLED);
|
||||
wait(tr.commit());
|
||||
break;
|
||||
} catch (Error& e) {
|
||||
|
@ -730,6 +735,7 @@ ACTOR Future<ClientLibStatus> getClientLibraryStatus(Database db, Standalone<Str
|
|||
loop {
|
||||
try {
|
||||
tr.setOption(FDBTransactionOptions::READ_SYSTEM_KEYS);
|
||||
tr.setOption(FDBTransactionOptions::READ_LOCK_AWARE);
|
||||
Optional<Value> metadataOpt = wait(tr.get(clientLibMetaKey));
|
||||
if (!metadataOpt.present()) {
|
||||
TraceEvent(SevWarnAlways, "ClientLibraryNotFound").detail("Key", clientLibMetaKey);
|
||||
|
@ -762,6 +768,7 @@ ACTOR Future<Void> changeClientLibraryStatus(Database db,
|
|||
tr = Transaction(db);
|
||||
try {
|
||||
tr.setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
|
||||
tr.setOption(FDBTransactionOptions::LOCK_AWARE);
|
||||
Optional<Value> metadataOpt = wait(tr.get(clientLibMetaKey));
|
||||
if (!metadataOpt.present()) {
|
||||
TraceEvent(SevWarnAlways, "ClientLibraryNotFound").detail("Key", clientLibMetaKey);
|
||||
|
@ -776,7 +783,7 @@ ACTOR Future<Void> changeClientLibraryStatus(Database db,
|
|||
jsStr = json_spirit::write_string(json_spirit::mValue(metadataJson));
|
||||
tr.set(clientLibMetaKey, ValueRef(jsStr));
|
||||
|
||||
updateClientLibChangeCounter(tr, newStatus);
|
||||
updateClientLibChangeCounter(tr, prevStatus, newStatus);
|
||||
|
||||
wait(tr.commit());
|
||||
break;
|
||||
|
|
|
@ -216,6 +216,7 @@ struct ClientLibManagementWorkload : public TestWorkload {
|
|||
self->success = false;
|
||||
}
|
||||
|
||||
// Clients should be notified about upload of a library with the active status
|
||||
Optional<Void> notificationWait = wait(timeout(clientLibChanged, 100.0));
|
||||
if (!notificationWait.present()) {
|
||||
TraceEvent(SevError, "ClientLibChangeNotificationFailed").log();
|
||||
|
@ -266,7 +267,15 @@ struct ClientLibManagementWorkload : public TestWorkload {
|
|||
}
|
||||
|
||||
ACTOR static Future<Void> testDeleteClientLib(ClientLibManagementWorkload* self, Database cx) {
|
||||
state Future<Void> clientLibChanged = cx->onClientLibStatusChanged();
|
||||
|
||||
wait(deleteClientLibrary(cx, self->uploadedClientLibId));
|
||||
|
||||
// Clients should be notified about deletion of the library, because it has "download" status
|
||||
Optional<Void> notificationWait = wait(timeout(clientLibChanged, 100.0));
|
||||
if (!notificationWait.present()) {
|
||||
TraceEvent(SevError, "ClientLibChangeNotificationFailed").log();
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
|
@ -349,6 +358,7 @@ struct ClientLibManagementWorkload : public TestWorkload {
|
|||
|
||||
ACTOR static Future<Void> testDisableClientLib(ClientLibManagementWorkload* self, Database cx) {
|
||||
state std::string destFileName = format("clientLibDownload%d", self->clientId);
|
||||
state Future<Void> clientLibChanged = cx->onClientLibStatusChanged();
|
||||
|
||||
// Set disabled status on the uploaded library
|
||||
wait(changeClientLibraryStatus(cx, self->uploadedClientLibId, ClientLibStatus::DISABLED));
|
||||
|
@ -361,11 +371,19 @@ struct ClientLibManagementWorkload : public TestWorkload {
|
|||
self->success = false;
|
||||
}
|
||||
|
||||
// Clients should be notified about an active library being disabled
|
||||
Optional<Void> notificationWait = wait(timeout(clientLibChanged, 100.0));
|
||||
if (!notificationWait.present()) {
|
||||
TraceEvent(SevError, "ClientLibChangeNotificationFailed").log();
|
||||
self->success = false;
|
||||
}
|
||||
|
||||
// It should not be possible to download a disabled client library
|
||||
wait(testExpectedError(downloadClientLibrary(cx, self->uploadedClientLibId, StringRef(destFileName)),
|
||||
"Downloading disabled client library",
|
||||
client_lib_not_available(),
|
||||
&self->success));
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue