mirror of
https://github.com/redis/redis.git
synced 2026-05-28 04:02:46 -04:00
GCRA param renaming (#14950)
Some checks are pending
CI / test-ubuntu-latest (push) Waiting to run
CI / test-sanitizer-address (push) Waiting to run
CI / build-debian-old (push) Waiting to run
CI / build-macos-latest (push) Waiting to run
CI / build-32bit (push) Waiting to run
CI / build-libc-malloc (push) Waiting to run
CI / build-centos-jemalloc (push) Waiting to run
CI / build-old-chain-jemalloc (push) Waiting to run
Codecov / code-coverage (push) Waiting to run
External Server Tests / test-external-standalone (push) Waiting to run
External Server Tests / test-external-cluster (push) Waiting to run
External Server Tests / test-external-nodebug (push) Waiting to run
Reply-schemas linter / reply-schemas-linter (push) Waiting to run
Spellcheck / Spellcheck (push) Waiting to run
Some checks are pending
CI / test-ubuntu-latest (push) Waiting to run
CI / test-sanitizer-address (push) Waiting to run
CI / build-debian-old (push) Waiting to run
CI / build-macos-latest (push) Waiting to run
CI / build-32bit (push) Waiting to run
CI / build-libc-malloc (push) Waiting to run
CI / build-centos-jemalloc (push) Waiting to run
CI / build-old-chain-jemalloc (push) Waiting to run
Codecov / code-coverage (push) Waiting to run
External Server Tests / test-external-standalone (push) Waiting to run
External Server Tests / test-external-cluster (push) Waiting to run
External Server Tests / test-external-nodebug (push) Waiting to run
Reply-schemas linter / reply-schemas-linter (push) Waiting to run
Spellcheck / Spellcheck (push) Waiting to run
Renames the `GCRA` command interface to use token terminology: `requests-per-period` becomes `tokens-per-period`, and the optional `NUM_REQUESTS` argument becomes `TOKENS` (with corresponding error messages/documentation updates).
This commit is contained in:
parent
b22ce4abb5
commit
ef536f48fd
4 changed files with 31 additions and 31 deletions
|
|
@ -11062,9 +11062,9 @@ keySpec GCRA_Keyspecs[1] = {
|
|||
struct COMMAND_ARG GCRA_Args[] = {
|
||||
{MAKE_ARG("key",ARG_TYPE_KEY,0,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("max-burst",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("requests-per-period",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("tokens-per-period",ARG_TYPE_INTEGER,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("period",ARG_TYPE_DOUBLE,-1,NULL,NULL,NULL,CMD_ARG_NONE,0,NULL)},
|
||||
{MAKE_ARG("count",ARG_TYPE_INTEGER,-1,"NUM_REQUESTS",NULL,NULL,CMD_ARG_OPTIONAL,0,NULL)},
|
||||
{MAKE_ARG("count",ARG_TYPE_INTEGER,-1,"TOKENS",NULL,NULL,CMD_ARG_OPTIONAL,0,NULL)},
|
||||
};
|
||||
|
||||
/********** GET ********************/
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"name": "requests-per-period",
|
||||
"name": "tokens-per-period",
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
{
|
||||
"name": "count",
|
||||
"type": "integer",
|
||||
"token": "NUM_REQUESTS",
|
||||
"token": "TOKENS",
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
|
|
|
|||
32
src/gcra.c
32
src/gcra.c
|
|
@ -65,21 +65,21 @@
|
|||
*
|
||||
* (ASCII art adapted from https://brandur.org/rate-limiting). */
|
||||
|
||||
/* GCRA key max_burst requests_per_period period [NUM_REQUESTS count]
|
||||
/* GCRA key max_burst tokens_per_period period [TOKENS count]
|
||||
*
|
||||
* key: Key related to specific rate limiting case
|
||||
* max_burst: Maximum requests allowed as burst (in addition to sustained rate)
|
||||
* requests_per_period: Number of requests allowed per period
|
||||
* max_burst: Maximum tokens allowed as burst (in addition to sustained rate)
|
||||
* tokens_per_period: Number of tokens allowed per period
|
||||
* period: Period in seconds for calculating sustained rate
|
||||
* num_requests: Optional, cost of this request (default: 1)
|
||||
* tokens: Optional, cost of this request (default: 1)
|
||||
*/
|
||||
void gcraCommand(client *c) {
|
||||
robj *key = c->argv[1];
|
||||
|
||||
/* GCRA parameters */
|
||||
long max_burst;
|
||||
long requests_per_period;
|
||||
long num_requests = 1;
|
||||
long tokens_per_period;
|
||||
long num_tokens = 1;
|
||||
double period;
|
||||
|
||||
/* Variables used in the reply */
|
||||
|
|
@ -98,7 +98,7 @@ void gcraCommand(client *c) {
|
|||
}
|
||||
if (likely(max_burst < LONG_MAX)) max_burst += 1;
|
||||
|
||||
if (getRangeLongFromObjectOrReply(c, c->argv[3], 1, LONG_MAX, &requests_per_period, NULL) != C_OK) {
|
||||
if (getRangeLongFromObjectOrReply(c, c->argv[3], 1, LONG_MAX, &tokens_per_period, NULL) != C_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -111,15 +111,15 @@ void gcraCommand(client *c) {
|
|||
}
|
||||
|
||||
if (c->argc >= 6) {
|
||||
if (strcasecmp("NUM_REQUESTS", c->argv[5]->ptr)) {
|
||||
if (strcasecmp("tokens", c->argv[5]->ptr)) {
|
||||
addReplyErrorObject(c, shared.syntaxerr);
|
||||
return;
|
||||
}
|
||||
if (c->argc == 6) {
|
||||
addReplyError(c, "Missing NUM_REQUESTS value");
|
||||
addReplyError(c, "Missing TOKENS value");
|
||||
return;
|
||||
}
|
||||
if (getRangeLongFromObjectOrReply(c, c->argv[6], 1, LONG_MAX, &num_requests, NULL) != C_OK) {
|
||||
if (getRangeLongFromObjectOrReply(c, c->argv[6], 1, LONG_MAX, &num_tokens, NULL) != C_OK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -158,18 +158,18 @@ void gcraCommand(client *c) {
|
|||
* Even if emission_interval_us becomes less than 1us, we assume it's min
|
||||
* 1ms. The API is already in seconds granularity so it is expected the user
|
||||
* won't need a submicrosecond accuracy. */
|
||||
long long emission_interval_us = (long long)(period_us / requests_per_period + 0.5);
|
||||
long long emission_interval_us = (long long)(period_us / tokens_per_period + 0.5);
|
||||
if (unlikely(emission_interval_us == 0)) emission_interval_us = 1;
|
||||
|
||||
/* overflow checks. In normal circumstances we shouldn't get these but the
|
||||
* user may have wrongfully specified very large values.
|
||||
* Note that all values are positive. */
|
||||
if (emission_interval_us > LLONG_MAX / num_requests) {
|
||||
addReplyError(c, "GCRA limiting uses microsecond accuracy. Combination of period, requests_per_period and num_requests would cause an overflow");
|
||||
if (emission_interval_us > LLONG_MAX / num_tokens) {
|
||||
addReplyError(c, "GCRA limiting uses microsecond accuracy. Combination of period, tokens_per_period and TOKENS would cause an overflow");
|
||||
return;
|
||||
}
|
||||
if (emission_interval_us > LLONG_MAX / max_burst) {
|
||||
addReplyError(c, "GCRA limiting uses microsecond accuracy. Combination of period, requests_per_period and max_burst would cause an overflow");
|
||||
addReplyError(c, "GCRA limiting uses microsecond accuracy. Combination of period, tokens_per_period and max_burst would cause an overflow");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -180,11 +180,11 @@ void gcraCommand(client *c) {
|
|||
|
||||
/* If a request is allowed the next TaT is after an emission_interval_us time.
|
||||
* Hence for multiple requests we multiple by their number. */
|
||||
long long increment_us = emission_interval_us * num_requests;
|
||||
long long increment_us = emission_interval_us * num_tokens;
|
||||
|
||||
long long base_us = (now > tat_us) ? now : tat_us;
|
||||
if (LLONG_MAX - base_us < increment_us) {
|
||||
addReplyError(c, "GCRA limiting uses microsecond accuracy. Combination of period, requests_per_period and num_requests would cause an overflow");
|
||||
addReplyError(c, "GCRA limiting uses microsecond accuracy. Combination of period, tokens_per_period and TOKENS would cause an overflow");
|
||||
return;
|
||||
}
|
||||
new_tat_us = base_us + increment_us;
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ start_server {tags {"gcra" "external:skip"}} {
|
|||
assert_match "*not a valid float*" $err
|
||||
|
||||
# tokens (optional) must be >= 1
|
||||
catch {r gcra mykey 10 5 10 NUM_REQUESTS} err
|
||||
assert_match "*Missing NUM_REQUESTS value*" $err
|
||||
catch {r gcra mykey 10 5 10 NUM_REQUESTS 0} err
|
||||
catch {r gcra mykey 10 5 10 TOKENS} err
|
||||
assert_match "*Missing TOKENS value*" $err
|
||||
catch {r gcra mykey 10 5 10 TOKENS 0} err
|
||||
assert_match "*out of range*" $err
|
||||
catch {r gcra mykey 10 5 10 NUM_REQUESTS -1} err
|
||||
catch {r gcra mykey 10 5 10 TOKENS -1} err
|
||||
assert_match "*out of range*" $err
|
||||
catch {r gcra mykey 10 5 10 NUM_REQUESTS notanumber} err
|
||||
catch {r gcra mykey 10 5 10 TOKENS notanumber} err
|
||||
assert_match "*not an integer*" $err
|
||||
|
||||
# Valid arguments with default tokens
|
||||
|
|
@ -53,7 +53,7 @@ start_server {tags {"gcra" "external:skip"}} {
|
|||
|
||||
# Valid arguments with explicit tokens
|
||||
r del mykey
|
||||
set result [r gcra mykey 10 5 60 NUM_REQUESTS 2]
|
||||
set result [r gcra mykey 10 5 60 TOKENS 2]
|
||||
assert_equal 5 [llength $result]
|
||||
assert_equal 11 [lindex $result 1]
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ start_server {tags {"gcra" "external:skip"}} {
|
|||
|
||||
r del mykey
|
||||
# Consume 3 tokens from fresh state
|
||||
set result2 [r gcra mykey 5 1 60 NUM_REQUESTS 3]
|
||||
set result2 [r gcra mykey 5 1 60 TOKENS 3]
|
||||
set avail2 [lindex $result2 2]
|
||||
assert_equal 3 $avail2
|
||||
}
|
||||
|
|
@ -168,7 +168,7 @@ start_server {tags {"gcra" "external:skip"}} {
|
|||
|
||||
r del mykey
|
||||
r gcra mykey 5 1 60
|
||||
set result [r gcra mykey 5 1 60 NUM_REQUESTS 4]
|
||||
set result [r gcra mykey 5 1 60 TOKENS 4]
|
||||
set full_burst_after [lindex $result 4]
|
||||
assert {$full_burst_after >= 299}
|
||||
}
|
||||
|
|
@ -216,7 +216,7 @@ start_server {tags {"gcra" "external:skip"}} {
|
|||
|
||||
test {GCRA - overflow} {
|
||||
r del mykey
|
||||
catch {r gcra mykey 1 1 86400 NUM_REQUESTS 200000000} err
|
||||
catch {r gcra mykey 1 1 86400 TOKENS 200000000} err
|
||||
assert_match "*would cause an overflow*" $err
|
||||
|
||||
r del mykey
|
||||
|
|
@ -224,7 +224,7 @@ start_server {tags {"gcra" "external:skip"}} {
|
|||
assert_match "*would cause an overflow*" $err
|
||||
|
||||
r del mykey
|
||||
catch {r gcra mykey 1 1 2147483647 NUM_REQUESTS 2147483647} err
|
||||
catch {r gcra mykey 1 1 2147483647 TOKENS 2147483647} err
|
||||
assert_match "*would cause an overflow*" $err
|
||||
}
|
||||
}
|
||||
|
|
@ -255,7 +255,7 @@ start_server {tags {"gcra repl" "external:skip"}} {
|
|||
assert_equal [lsearch -glob $cmdinfo "cmdstat_set:*"] -1
|
||||
|
||||
$master del mykey
|
||||
$master gcra mykey 2 1 1000 NUM_REQUESTS 2
|
||||
$master gcra mykey 2 1 1000 TOKENS 2
|
||||
|
||||
wait_for_ofs_sync $master $replica
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue