Skip to content

Commit f6c9fe3

Browse files
committed
GCRA: reflect name/protocol change from redis/redis#14950 (note: need a new CI build before we can validate this)
1 parent 0c58866 commit f6c9fe3

17 files changed

Lines changed: 131 additions & 113 deletions

docs/ReleaseNotes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Current package versions:
88

99
## Unreleased
1010

11-
- (none)
11+
- Update experimental `GCRA` APIs and wire protocol terminology from "requests" to "tokens", to match server change ([#PR by @mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/PR))
1212

1313
## 2.12.14
1414

src/StackExchange.Redis/ExtensionMethods.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ internal static int VectorSafeIndexOfCRLF(this ReadOnlySpan<byte> span)
346346
/// <param name="database">The database instance.</param>
347347
/// <param name="key">The key for the rate limiter.</param>
348348
/// <param name="maxBurst">The maximum burst size.</param>
349-
/// <param name="requestsPerPeriod">The number of requests allowed per period.</param>
349+
/// <param name="tokensPerPeriod">The number of tokens allowed per period.</param>
350350
/// <param name="allow">The maximum time to wait for a successful acquisition.</param>
351351
/// <param name="periodSeconds">The period in seconds (default: 1.0).</param>
352352
/// <param name="count">The number of tokens to acquire (default: 1).</param>
@@ -358,7 +358,7 @@ public static async ValueTask<bool> TryAcquireGcraAsync(
358358
this IDatabaseAsync database,
359359
RedisKey key,
360360
int maxBurst,
361-
int requestsPerPeriod,
361+
int tokensPerPeriod,
362362
TimeSpan allow,
363363
double periodSeconds = 1.0,
364364
int count = 1,
@@ -372,7 +372,7 @@ public static async ValueTask<bool> TryAcquireGcraAsync(
372372

373373
while (true)
374374
{
375-
var result = await database.StringGcraRateLimitAsync(key, maxBurst, requestsPerPeriod, periodSeconds, count, flags).ConfigureAwait(false);
375+
var result = await database.StringGcraRateLimitAsync(key, maxBurst, tokensPerPeriod, periodSeconds, count, flags).ConfigureAwait(false);
376376

377377
if (!result.Limited)
378378
{

src/StackExchange.Redis/Gcra.GcraMessage.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,22 @@ internal sealed class GcraMessage(
77
CommandFlags flags,
88
RedisKey key,
99
int maxBurst,
10-
int requestsPerPeriod,
10+
int tokensPerPeriod,
1111
double periodSeconds,
1212
int count) : Message(database, flags, RedisCommand.GCRA)
1313
{
1414
protected override void WriteImpl(PhysicalConnection connection)
1515
{
16-
// GCRA key max_burst requests_per_period period [NUM_REQUESTS count]
16+
// GCRA key max_burst tokens_per_period period [TOKENS count]
1717
connection.WriteHeader(Command, ArgCount);
1818
connection.WriteBulkString(key);
1919
connection.WriteBulkString(maxBurst);
20-
connection.WriteBulkString(requestsPerPeriod);
20+
connection.WriteBulkString(tokensPerPeriod);
2121
connection.WriteBulkString(periodSeconds);
2222

2323
if (count != 1)
2424
{
25-
connection.WriteBulkString("NUM_REQUESTS"u8);
25+
connection.WriteBulkString("TOKENS"u8);
2626
connection.WriteBulkString(count);
2727
}
2828
}
@@ -31,8 +31,8 @@ public override int ArgCount
3131
{
3232
get
3333
{
34-
int argCount = 4; // key, max_burst, requests_per_period, period
35-
if (count != 1) argCount += 2; // NUM_REQUESTS, count
34+
int argCount = 4; // key, max_burst, tokens_per_period, period
35+
if (count != 1) argCount += 2; // TOKENS, count
3636
return argCount;
3737
}
3838
}

src/StackExchange.Redis/Gcra.GcraRateLimitResult.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ namespace StackExchange.Redis;
1010
public readonly partial struct GcraRateLimitResult
1111
{
1212
/// <summary>
13-
/// Indicates whether the request was rate limited (true) or allowed (false).
13+
/// Indicates whether the token acquisition was rate limited (true) or allowed (false).
1414
/// </summary>
1515
public bool Limited { get; }
1616

1717
/// <summary>
18-
/// The maximum number of requests allowed. Always equal to max_burst + 1.
18+
/// The maximum number of tokens allowed. Always equal to max_burst + 1.
1919
/// </summary>
20-
public int MaxRequests { get; }
20+
public int MaxTokens { get; }
2121

2222
/// <summary>
23-
/// The number of requests available immediately without being rate limited.
23+
/// The number of tokens available immediately without being rate limited.
2424
/// </summary>
25-
public int AvailableRequests { get; }
25+
public int AvailableTokens { get; }
2626

2727
/// <summary>
2828
/// The number of seconds after which the caller should retry.
29-
/// Returns -1 if the request is not limited.
29+
/// Returns -1 if the token acquisition is not limited.
3030
/// </summary>
3131
public int RetryAfterSeconds { get; }
3232

@@ -38,11 +38,11 @@ public readonly partial struct GcraRateLimitResult
3838
/// <summary>
3939
/// Initializes a new instance of the <see cref="GcraRateLimitResult"/> struct.
4040
/// </summary>
41-
public GcraRateLimitResult(bool limited, int maxRequests, int availableRequests, int retryAfterSeconds, int fullBurstAfterSeconds)
41+
public GcraRateLimitResult(bool limited, int maxTokens, int availableTokens, int retryAfterSeconds, int fullBurstAfterSeconds)
4242
{
4343
Limited = limited;
44-
MaxRequests = maxRequests;
45-
AvailableRequests = availableRequests;
44+
MaxTokens = maxTokens;
45+
AvailableTokens = availableTokens;
4646
RetryAfterSeconds = retryAfterSeconds;
4747
FullBurstAfterSeconds = fullBurstAfterSeconds;
4848
}

src/StackExchange.Redis/Gcra.ResultProcessor.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
1010
{
1111
// GCRA returns an array with 5 elements:
1212
// 1) <limited> # 0 or 1
13-
// 2) <max-req-num> # max number of request. Always equal to max_burst+1
14-
// 3) <num-avail-req> # number of requests available immediately
15-
// 4) <reply-after> # number of seconds after which caller should retry. Always returns -1 if request isn't limited.
13+
// 2) <max-token-num> # max number of tokens. Always equal to max_burst+1
14+
// 3) <num-avail-token> # number of tokens available immediately
15+
// 4) <reply-after> # number of seconds after which caller should retry. Always returns -1 if acquisition isn't limited.
1616
// 5) <full-burst-after> # number of seconds after which a full burst will be allowed
1717
if (result.Resp2TypeArray == ResultType.Array && result.ItemsCount >= 5)
1818
{
1919
var items = result.GetItems();
2020
bool limited = items[0].GetBoolean();
21-
if (items[1].TryGetInt64(out long maxRequests)
22-
&& items[2].TryGetInt64(out long availableRequests)
21+
if (items[1].TryGetInt64(out long maxTokens)
22+
&& items[2].TryGetInt64(out long availableTokens)
2323
&& items[3].TryGetInt64(out long retryAfterSeconds)
2424
&& items[4].TryGetInt64(out long fullBurstAfterSeconds))
2525
{
2626
var grca = new GcraRateLimitResult(
2727
limited: limited,
28-
maxRequests: (int)maxRequests,
29-
availableRequests: (int)availableRequests,
28+
maxTokens: (int)maxTokens,
29+
availableTokens: (int)availableTokens,
3030
retryAfterSeconds: (int)retryAfterSeconds,
3131
fullBurstAfterSeconds: (int)fullBurstAfterSeconds);
3232
SetResult(message, grca);
@@ -42,21 +42,21 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
4242
{
4343
// GCRA returns an array with 5 elements:
4444
// 1) <limited> # 0 or 1
45-
// 2) <max-req-num> # max number of request. Always equal to max_burst+1
46-
// 3) <num-avail-req> # number of requests available immediately
47-
// 4) <reply-after> # number of seconds after which caller should retry. Always returns -1 if request isn't limited.
45+
// 2) <max-token-num> # max number of tokens. Always equal to max_burst+1
46+
// 3) <num-avail-token> # number of tokens available immediately
47+
// 4) <reply-after> # number of seconds after which caller should retry. Always returns -1 if acquisition isn't limited.
4848
// 5) <full-burst-after> # number of seconds after which a full burst will be allowed
4949
if (reader.IsAggregate
5050
&& reader.TryMoveNext() && reader.IsScalar && reader.TryReadBoolean(out bool limited)
51-
&& reader.TryMoveNext() && reader.IsScalar && reader.TryReadInt64(out long maxRequests)
52-
&& reader.TryMoveNext() && reader.IsScalar && reader.TryReadInt64(out long availableRequests)
51+
&& reader.TryMoveNext() && reader.IsScalar && reader.TryReadInt64(out long maxTokens)
52+
&& reader.TryMoveNext() && reader.IsScalar && reader.TryReadInt64(out long availableTokens)
5353
&& reader.TryMoveNext() && reader.IsScalar && reader.TryReadInt64(out long retryAfterSeconds)
5454
&& reader.TryMoveNext() && reader.IsScalar && reader.TryReadInt64(out long fullBurstAfterSeconds))
5555
{
5656
var result = new GcraRateLimitResult(
5757
limited: limited,
58-
maxRequests: (int)maxRequests,
59-
availableRequests: (int)availableRequests,
58+
maxTokens: (int)maxTokens,
59+
availableTokens: (int)availableTokens,
6060
retryAfterSeconds: (int)retryAfterSeconds,
6161
fullBurstAfterSeconds: (int)fullBurstAfterSeconds);
6262
SetResult(message, result);

src/StackExchange.Redis/Interfaces/IDatabase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3259,14 +3259,14 @@ IEnumerable<SortedSetEntry> SortedSetScan(
32593259
/// </summary>
32603260
/// <param name="key">The key to rate limit.</param>
32613261
/// <param name="maxBurst">The maximum burst size.</param>
3262-
/// <param name="requestsPerPeriod">The number of requests allowed per period.</param>
3262+
/// <param name="tokensPerPeriod">The number of tokens allowed per period.</param>
32633263
/// <param name="periodSeconds">The period duration in seconds. Default is 1.0.</param>
3264-
/// <param name="count">The number of requests to consume. Default is 1.</param>
3264+
/// <param name="count">The number of tokens to consume. Default is 1.</param>
32653265
/// <param name="flags">The flags to use for this operation.</param>
32663266
/// <returns>A <see cref="GcraRateLimitResult"/> containing the rate limit decision and metadata.</returns>
32673267
/// <remarks><seealso href="https://redis.io/commands/gcra"/></remarks>
32683268
[Experimental(Experiments.Server_8_8, UrlFormat = Experiments.UrlFormat)]
3269-
GcraRateLimitResult StringGcraRateLimit(RedisKey key, int maxBurst, int requestsPerPeriod, double periodSeconds = 1.0, int count = 1, CommandFlags flags = CommandFlags.None);
3269+
GcraRateLimitResult StringGcraRateLimit(RedisKey key, int maxBurst, int tokensPerPeriod, double periodSeconds = 1.0, int count = 1, CommandFlags flags = CommandFlags.None);
32703270

32713271
/// <summary>
32723272
/// Get the value of key. If the key does not exist the special value <see cref="RedisValue.Null"/> is returned.

src/StackExchange.Redis/Interfaces/IDatabaseAsync.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ IAsyncEnumerable<SortedSetEntry> SortedSetScanAsync(
797797

798798
/// <inheritdoc cref="IDatabase.StringGcraRateLimit(RedisKey, int, int, double, int, CommandFlags)"/>
799799
[Experimental(Experiments.Server_8_8, UrlFormat = Experiments.UrlFormat)]
800-
Task<GcraRateLimitResult> StringGcraRateLimitAsync(RedisKey key, int maxBurst, int requestsPerPeriod, double periodSeconds = 1.0, int count = 1, CommandFlags flags = CommandFlags.None);
800+
Task<GcraRateLimitResult> StringGcraRateLimitAsync(RedisKey key, int maxBurst, int tokensPerPeriod, double periodSeconds = 1.0, int count = 1, CommandFlags flags = CommandFlags.None);
801801

802802
/// <inheritdoc cref="IDatabase.StringGet(RedisKey, CommandFlags)"/>
803803
Task<RedisValue> StringGetAsync(RedisKey key, CommandFlags flags = CommandFlags.None);

src/StackExchange.Redis/KeyspaceIsolation/KeyPrefixed.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,8 +792,8 @@ public Task<long> StringIncrementAsync(RedisKey key, long value = 1, CommandFlag
792792
public Task<long> StringLengthAsync(RedisKey key, CommandFlags flags = CommandFlags.None) =>
793793
Inner.StringLengthAsync(ToInner(key), flags);
794794

795-
public Task<GcraRateLimitResult> StringGcraRateLimitAsync(RedisKey key, int maxBurst, int requestsPerPeriod, double period = 1.0, int count = 1, CommandFlags flags = CommandFlags.None) =>
796-
Inner.StringGcraRateLimitAsync(ToInner(key), maxBurst, requestsPerPeriod, period, count, flags);
795+
public Task<GcraRateLimitResult> StringGcraRateLimitAsync(RedisKey key, int maxBurst, int tokensPerPeriod, double period = 1.0, int count = 1, CommandFlags flags = CommandFlags.None) =>
796+
Inner.StringGcraRateLimitAsync(ToInner(key), maxBurst, tokensPerPeriod, period, count, flags);
797797

798798
public Task<bool> StringSetAsync(RedisKey key, RedisValue value, Expiration expiry, ValueCondition when, CommandFlags flags = CommandFlags.None)
799799
=> Inner.StringSetAsync(ToInner(key), value, expiry, when, flags);

src/StackExchange.Redis/KeyspaceIsolation/KeyPrefixedDatabase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,8 +774,8 @@ public long StringIncrement(RedisKey key, long value = 1, CommandFlags flags = C
774774
public long StringLength(RedisKey key, CommandFlags flags = CommandFlags.None) =>
775775
Inner.StringLength(ToInner(key), flags);
776776

777-
public GcraRateLimitResult StringGcraRateLimit(RedisKey key, int maxBurst, int requestsPerPeriod, double period = 1.0, int count = 1, CommandFlags flags = CommandFlags.None) =>
778-
Inner.StringGcraRateLimit(ToInner(key), maxBurst, requestsPerPeriod, period, count, flags);
777+
public GcraRateLimitResult StringGcraRateLimit(RedisKey key, int maxBurst, int tokensPerPeriod, double period = 1.0, int count = 1, CommandFlags flags = CommandFlags.None) =>
778+
Inner.StringGcraRateLimit(ToInner(key), maxBurst, tokensPerPeriod, period, count, flags);
779779

780780
public bool StringSet(RedisKey key, RedisValue value, Expiration expiry, ValueCondition when, CommandFlags flags = CommandFlags.None)
781781
=> Inner.StringSet(ToInner(key), value, expiry, when, flags);

0 commit comments

Comments
 (0)