Encoding of tags in the database now supports multiple tags per throttle. Remove throttle prefix search.
This commit is contained in:
parent
ebeca10bce
commit
55a0d00ad4
|
@ -3788,17 +3788,16 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
|
|||
continue;
|
||||
}
|
||||
else if(tokencmp(tokens[1], "list")) {
|
||||
if(tokens.size() > 4) {
|
||||
printf("Usage: throttle list [LIMIT] [PREFIX]\n");
|
||||
if(tokens.size() > 3) {
|
||||
printf("Usage: throttle list [LIMIT]\n");
|
||||
printf("\n");
|
||||
printf("Lists tags that are currently throttled, optionally limited to a certain tag PREFIX.\n");
|
||||
printf("The default LIMIT is 100 tags, and by default all tags will be searched.\n");
|
||||
printf("Lists tags that are currently throttled.\n");
|
||||
printf("The default LIMIT is 100 tags.\n");
|
||||
is_error = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
state int throttleListLimit = 100;
|
||||
state StringRef prefix;
|
||||
if(tokens.size() >= 3) {
|
||||
char *end;
|
||||
throttleListLimit = std::strtol((const char*)tokens[2].begin(), &end, 10);
|
||||
|
@ -3808,19 +3807,11 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if(tokens.size() >= 4) {
|
||||
prefix = tokens[3];
|
||||
}
|
||||
|
||||
std::map<Standalone<StringRef>, TagThrottleInfo> tags = wait(ThrottleApi::getTags(db, throttleListLimit, prefix));
|
||||
|
||||
std::string prefixString = "";
|
||||
if(prefix.size() > 0) {
|
||||
prefixString = format(" with prefix `%s'", prefix.toString().c_str());
|
||||
}
|
||||
std::map<Standalone<StringRef>, TagThrottleInfo> tags = wait(ThrottleApi::getTags(db, throttleListLimit));
|
||||
|
||||
if(tags.size() > 0) {
|
||||
printf("Throttled tags%s:\n\n", prefixString.c_str());
|
||||
printf("Throttled tags:\n\n");
|
||||
printf(" Rate | Expiration (s) | Priority | Type | Tag\n");
|
||||
printf(" ------+----------------+-----------+--------+------------------\n");
|
||||
for(auto itr = tags.begin(); itr != tags.end(); ++itr) {
|
||||
|
@ -3829,16 +3820,16 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise) {
|
|||
(int)(itr->second.expiration-now()),
|
||||
TagThrottleInfo::priorityToString(itr->second.priority),
|
||||
itr->second.autoThrottled ? "auto" : "manual",
|
||||
itr->first.substr(tagThrottleKeysPrefix.size()).toString().c_str());
|
||||
itr->first.toString().c_str());
|
||||
}
|
||||
|
||||
if(tags.size() == throttleListLimit) {
|
||||
printf("\nThe tag limit `%d' was reached. Use the [LIMIT] or [PREFIX] arguments to view additional tags.\n", throttleListLimit);
|
||||
printf("Usage: throttle list [LIMIT] [PREFIX]\n");
|
||||
printf("\nThe tag limit `%d' was reached. Use the [LIMIT] argument to view additional tags.\n", throttleListLimit);
|
||||
printf("Usage: throttle list [LIMIT]\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("There are no throttled tags%s\n", prefixString.c_str());
|
||||
printf("There are no throttled tags\n");
|
||||
}
|
||||
}
|
||||
else if(tokencmp(tokens[1], "on") && tokens.size() <=6) {
|
||||
|
|
|
@ -3275,8 +3275,6 @@ ACTOR Future<Version> extractReadVersion(DatabaseContext* cx, uint32_t flags, Re
|
|||
if(rep.locked && !lockAware)
|
||||
throw database_locked();
|
||||
|
||||
TagThrottleInfo::Priority priority;
|
||||
|
||||
++cx->transactionReadVersionsCompleted;
|
||||
|
||||
auto &priorityThrottledTags = cx->throttledTags[TagThrottleInfo::priorityFromReadVersionFlags(flags)];
|
||||
|
|
|
@ -62,7 +62,52 @@ namespace ThrottleApi {
|
|||
tr.atomicOp(tagThrottleSignalKey, LiteralStringRef("XXXXXXXXXX\x00\x00\x00\x00"), MutationRef::SetVersionstampedValue);
|
||||
}
|
||||
|
||||
ACTOR Future<std::map<Standalone<StringRef>, TagThrottleInfo>> getTags(Database db, int limit, KeyRef prefix) {
|
||||
// Format for throttle key:
|
||||
//
|
||||
// tagThrottleKeysPrefix + [tag list]
|
||||
// tag list consists of 1 or more consecutive tags, each encoded as:
|
||||
// tag.size() (1 byte) + tag's bytes. For example, tag 'foo' is: \x03foo
|
||||
// The tags are listed in sorted order
|
||||
//
|
||||
// Currently, the throttle API supports only 1 tag per throttle
|
||||
Standalone<StringRef> throttleKeyForTags(std::set<StringRef> const& tags) {
|
||||
ASSERT(CLIENT_KNOBS->MAX_TRANSACTION_TAG_LENGTH < 256);
|
||||
ASSERT(tags.size() > 0);
|
||||
|
||||
ASSERT(tags.size() == 1); // TODO: support multiple tags per throttle
|
||||
|
||||
int size = tagThrottleKeysPrefix.size() + tags.size();
|
||||
for(auto tag : tags) {
|
||||
ASSERT(tag.size() <= CLIENT_KNOBS->MAX_TRANSACTION_TAG_LENGTH);
|
||||
size += tag.size();
|
||||
}
|
||||
|
||||
Key result;
|
||||
|
||||
uint8_t* str = new (result.arena()) uint8_t[size];
|
||||
result.contents() = StringRef(str, size);
|
||||
|
||||
memcpy(str, tagThrottleKeysPrefix.begin(), tagThrottleKeysPrefix.size());
|
||||
str += tagThrottleKeysPrefix.size();
|
||||
|
||||
for(auto tag : tags) {
|
||||
*(str++) = (uint8_t)tag.size();
|
||||
if(tag.size() > 0) {
|
||||
memcpy(str, tag.begin(), tag.size());
|
||||
str += tag.size();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
StringRef tagFromThrottleKey(KeyRef key) {
|
||||
StringRef tag = key.substr(tagThrottleKeysPrefix.size()+1);
|
||||
ASSERT(tag.size() == key.begin()[tagThrottleKeysPrefix.size()]); // TODO: support multiple tags per throttle
|
||||
return tag;
|
||||
}
|
||||
|
||||
ACTOR Future<std::map<Standalone<StringRef>, TagThrottleInfo>> getTags(Database db, int limit) {
|
||||
state Transaction tr(db);
|
||||
|
||||
loop {
|
||||
|
@ -70,7 +115,7 @@ namespace ThrottleApi {
|
|||
Standalone<RangeResultRef> tags = wait(tr.getRange(tagThrottleKeys, limit));
|
||||
std::map<Standalone<StringRef>, TagThrottleInfo> results;
|
||||
for(auto tag : tags) {
|
||||
results[tag.key] = decodeTagThrottleValue(tag.value);
|
||||
results[tagFromThrottleKey(tag.key)] = decodeTagThrottleValue(tag.value);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
@ -82,7 +127,7 @@ namespace ThrottleApi {
|
|||
|
||||
ACTOR Future<Void> throttleTag(Database db, Standalone<StringRef> tag, double rate, double expiration, bool serializeExpirationAsDuration, bool autoThrottled) {
|
||||
state Transaction tr(db);
|
||||
state Key key = tag.withPrefix(tagThrottleKeysPrefix);
|
||||
state Key key = throttleKeyForTags(std::set<StringRef>{ tag });
|
||||
|
||||
TagThrottleInfo throttle(rate, expiration, autoThrottled, TagThrottleInfo::Priority::DEFAULT, serializeExpirationAsDuration);
|
||||
BinaryWriter wr(IncludeVersion());
|
||||
|
@ -108,7 +153,7 @@ namespace ThrottleApi {
|
|||
|
||||
ACTOR Future<bool> unthrottleTag(Database db, Standalone<StringRef> tag) {
|
||||
state Transaction tr(db);
|
||||
state Key key = tag.withPrefix(tagThrottleKeysPrefix);
|
||||
state Key key = throttleKeyForTags(std::set<StringRef>{ tag });
|
||||
|
||||
loop {
|
||||
try {
|
||||
|
|
|
@ -151,7 +151,11 @@ struct dynamic_size_traits<TagSet> : std::true_type {
|
|||
BINARY_SERIALIZABLE(TagThrottleInfo::Priority);
|
||||
|
||||
namespace ThrottleApi {
|
||||
Future<std::map<Standalone<StringRef>, TagThrottleInfo>> getTags(Database const& db, int const& limit, KeyRef const& prefix);
|
||||
// Currently, only 1 tag in a key is supported
|
||||
Standalone<StringRef> throttleKeyForTags(std::set<StringRef> const& tags);
|
||||
StringRef tagFromThrottleKey(KeyRef key);
|
||||
|
||||
Future<std::map<Standalone<StringRef>, TagThrottleInfo>> getTags(Database const& db, int const& limit);
|
||||
|
||||
Future<Void> throttleTag(Database const& db, Standalone<StringRef> const& tag, double const& rate, double const& expiration,
|
||||
bool const& serializeExpirationAsDuration, bool const& autoThrottled); // TODO: priorities
|
||||
|
|
|
@ -424,7 +424,7 @@ ACTOR Future<Void> monitorThrottlingChanges(RatekeeperData *self) {
|
|||
}
|
||||
|
||||
for(auto entry : throttledTags.get()) {
|
||||
StringRef tag = entry.key.substr(tagThrottleKeysPrefix.size());
|
||||
StringRef tag = ThrottleApi::tagFromThrottleKey(entry.key);
|
||||
TagThrottleInfo throttleInfo = ThrottleApi::decodeTagThrottleValue(entry.value);
|
||||
TraceEvent("RatekeeperReadThrottleRead").detail("Tag", tag).detail("Expiration", throttleInfo.expiration);
|
||||
if((!self->autoThrottlingEnabled && throttleInfo.autoThrottled) || throttleInfo.expiration <= now()) { // TODO: keep or delete auto throttles when disabling auto-throttling
|
||||
|
|
Loading…
Reference in New Issue