Skip to content

Commit 3098a35

Browse files
committed
Fixes inconsistent SetIf*Async TTL behavior
Standardizes the behavior of the SetIfHigherAsync and SetIfLowerAsync methods regarding TTL handling. Previously, these methods returned -1 when a zero or negative TimeSpan was provided, leading to inconsistent behavior. Now, they consistently return 0 and remove the key, aligning with other cache methods.
1 parent 985f4ac commit 3098a35

File tree

3 files changed

+14
-18
lines changed

3 files changed

+14
-18
lines changed

docs/guide/caching.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ Different methods handle the `expiresIn` parameter slightly differently. The tab
7171
| `ReplaceAsync` | No TTL (removes existing) | Sets TTL | Removes key | `false` |
7272
| `ReplaceIfEqualAsync` | No TTL (removes existing) | Sets TTL | Removes key | `false` |
7373
| `IncrementAsync` | **Preserves existing TTL** | Sets/updates TTL | Removes key | `0` |
74-
| `SetIfHigherAsync` | No TTL (removes existing) | Sets TTL | Removes key | `-1` |
75-
| `SetIfLowerAsync` | No TTL (removes existing) | Sets TTL | Removes key | `-1` |
74+
| `SetIfHigherAsync` | No TTL (removes existing) | Sets TTL | Removes key | `0` |
75+
| `SetIfLowerAsync` | No TTL (removes existing) | Sets TTL | Removes key | `0` |
7676
| `ListAddAsync` | No TTL | Sets TTL | Removes key | `0` |
7777
| `ListRemoveAsync` | Preserves existing TTL | Sets TTL | Removes key | `0` |
7878

@@ -137,8 +137,8 @@ await cache.SetIfHigherAsync("max-users", 150, null); // No TTL now!
137137
// Update with TTL - sets new TTL
138138
await cache.SetIfHigherAsync("max-users", 200, TimeSpan.FromHours(2)); // TTL = 2 hours
139139
140-
// Zero/negative removes key, returns -1
141-
var diff = await cache.SetIfHigherAsync("max-users", 999, TimeSpan.Zero); // -1
140+
// Zero/negative removes key, returns 0
141+
var diff = await cache.SetIfHigherAsync("max-users", 999, TimeSpan.Zero); // 0
142142
```
143143

144144
### Managing Expiration

src/Foundatio/Caching/ICacheClient.cs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace Foundatio.Caching;
1717
/// When called on an existing key, passing null removes any existing expiration.</description></item>
1818
/// <item><description><b>Positive value</b>: The entry will expire after the specified duration from now.</description></item>
1919
/// <item><description><b>Zero or negative value</b>: The operation is treated as expired - any existing key is removed
20-
/// and the method returns a failure/default value (false, 0, -1, depending on the method).</description></item>
20+
/// and the method returns a failure/default value (false, 0, depending on the method).</description></item>
2121
/// <item><description><b>TimeSpan.MaxValue</b>: The entry will not expire (treated as no expiration).</description></item>
2222
/// </list>
2323
/// <para>
@@ -325,13 +325,12 @@ public interface ICacheClient : IDisposable
325325
/// <list type="bullet">
326326
/// <item><description><b>null</b>: Entry will not expire (removes any existing expiration).</description></item>
327327
/// <item><description><b>Positive value</b>: Entry expires after this duration.</description></item>
328-
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns -1.</description></item>
328+
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns 0.</description></item>
329329
/// </list>
330330
/// </param>
331331
/// <returns>
332332
/// The difference between the new value and the old value if the value was updated;
333-
/// 0 if the current value was already higher or equal;
334-
/// -1 if the operation failed due to invalid expiration.
333+
/// 0 if the current value was already higher or equal or invalid expiration.
335334
/// For new keys, returns the value itself (difference from 0).
336335
/// </returns>
337336
/// <exception cref="ArgumentNullException">Thrown when <paramref name="key"/> is null.</exception>
@@ -350,13 +349,12 @@ public interface ICacheClient : IDisposable
350349
/// <list type="bullet">
351350
/// <item><description><b>null</b>: Entry will not expire (removes any existing expiration).</description></item>
352351
/// <item><description><b>Positive value</b>: Entry expires after this duration.</description></item>
353-
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns -1.</description></item>
352+
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns 0.</description></item>
354353
/// </list>
355354
/// </param>
356355
/// <returns>
357356
/// The difference between the new value and the old value if the value was updated;
358-
/// 0 if the current value was already higher or equal;
359-
/// -1 if the operation failed due to invalid expiration.
357+
/// 0 if the current value was already higher or equal or invalid expiration.
360358
/// For new keys, returns the value itself (difference from 0).
361359
/// </returns>
362360
/// <exception cref="ArgumentNullException">Thrown when <paramref name="key"/> is null.</exception>
@@ -375,13 +373,12 @@ public interface ICacheClient : IDisposable
375373
/// <list type="bullet">
376374
/// <item><description><b>null</b>: Entry will not expire (removes any existing expiration).</description></item>
377375
/// <item><description><b>Positive value</b>: Entry expires after this duration.</description></item>
378-
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns -1.</description></item>
376+
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns 0.</description></item>
379377
/// </list>
380378
/// </param>
381379
/// <returns>
382380
/// The difference between the old value and the new value if the value was updated;
383-
/// 0 if the current value was already lower or equal;
384-
/// -1 if the operation failed due to invalid expiration.
381+
/// 0 if the current value was already lower or equal or invalid expiration.
385382
/// For new keys, returns the value itself (difference from 0).
386383
/// </returns>
387384
/// <exception cref="ArgumentNullException">Thrown when <paramref name="key"/> is null.</exception>
@@ -400,13 +397,12 @@ public interface ICacheClient : IDisposable
400397
/// <list type="bullet">
401398
/// <item><description><b>null</b>: Entry will not expire (removes any existing expiration).</description></item>
402399
/// <item><description><b>Positive value</b>: Entry expires after this duration.</description></item>
403-
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns -1.</description></item>
400+
/// <item><description><b>Zero or negative</b>: Any existing key is removed, returns 0.</description></item>
404401
/// </list>
405402
/// </param>
406403
/// <returns>
407404
/// The difference between the old value and the new value if the value was updated;
408-
/// 0 if the current value was already lower or equal;
409-
/// -1 if the operation failed due to invalid expiration.
405+
/// 0 if the current value was already lower or equal or invalid expiration.
410406
/// For new keys, returns the value itself (difference from 0).
411407
/// </returns>
412408
/// <exception cref="ArgumentNullException">Thrown when <paramref name="key"/> is null.</exception>

tests/Foundatio.Tests/Caching/InMemoryCacheClientTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ public async Task SetAsync_WithMaxItems_EnforcesLimit()
677677
[Fact]
678678
public async Task DoMaintenanceAsync_WithMaxTimeSpanExpiration_ShouldNotThrowException()
679679
{
680-
// Arrange - use normal time, not DateTimeOffset.MaxValue which causes overflow issues
680+
// Arrange - use a normal current time so using TimeSpan.MaxValue for expiration does not cause overflow issues
681681
var timeProvider = new FakeTimeProvider();
682682
timeProvider.SetUtcNow(new DateTimeOffset(2024, 1, 1, 0, 0, 0, TimeSpan.Zero));
683683

0 commit comments

Comments
 (0)