Skip to content

Commit 203a32b

Browse files
ITikhonovITikhonov
authored andcommitted
merge main
2 parents cb87bd8 + 145540d commit 203a32b

11 files changed

Lines changed: 102 additions & 23 deletions

File tree

docs/ReleaseNotes.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ From 3.0, [release notes will be maintained in GitHub only](https://github.com/S
1313
---
1414

1515

16-
## 2.12.14
17-
18-
- (none)
19-
2016
## 2.13.17
2117

2218
- Fix TCP platform-dependent TCP keep-alive problems, and make an explicit option. ([#3090 by @mgravell](https://github.com/StackExchange/StackExchange.Redis/pull/3090))

src/RESPite/PublicAPI/PublicAPI.Shipped.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,13 @@
210210
[SER004]virtual RESPite.Messages.RespReader.Projection<TState, TResult>.Invoke(ref TState state, ref RESPite.Messages.RespReader value) -> TResult
211211
[SER004]virtual RESPite.Messages.RespReader.ScalarParser<TSource, TValue>.Invoke(scoped System.ReadOnlySpan<TSource> value, out TValue result) -> bool
212212
[SER004]RESPite.Messages.RespReader.Serialize() -> byte[]!
213+
[SER004]RESPite.Messages.RespReader.TryParseScalar<T>(RESPite.Messages.RespReader.ScalarParser<char, T>! parser, out T value) -> bool
214+
[SER004]static RESPite.AsciiHash.EqualsCI(System.ReadOnlySpan<byte> first, System.ReadOnlySpan<char> second) -> bool
215+
[SER004]static RESPite.AsciiHash.EqualsCI(System.ReadOnlySpan<char> first, System.ReadOnlySpan<byte> second) -> bool
216+
[SER004]static RESPite.AsciiHash.SequenceEqualsCI(System.ReadOnlySpan<byte> first, System.ReadOnlySpan<char> second) -> bool
217+
[SER004]static RESPite.AsciiHash.SequenceEqualsCI(System.ReadOnlySpan<char> first, System.ReadOnlySpan<byte> second) -> bool
218+
[SER004]virtual RESPite.Buffers.CycleBufferPool<T>.Rent(in System.Buffers.ReadOnlySequence<T> existing) -> System.Buffers.IMemoryOwner<T>!
219+
[SER004]RESPite.Buffers.CycleBuffer.Pool.get -> System.Buffers.MemoryPool<byte>!
220+
[SER004]RESPite.Buffers.CycleBufferPool<T>
221+
[SER004]RESPite.Buffers.CycleBufferPool<T>.CycleBufferPool() -> void
222+
[SER004]static RESPite.Buffers.CycleBuffer.Create(System.Buffers.MemoryPool<byte>? pool = null, RESPite.Buffers.ICycleBufferCallback? callback = null) -> RESPite.Buffers.CycleBuffer
Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1 @@
1-
#nullable enable
2-
[SER004]RESPite.Messages.RespReader.TryParseScalar<T>(RESPite.Messages.RespReader.ScalarParser<char, T>! parser, out T value) -> bool
3-
[SER004]static RESPite.AsciiHash.EqualsCI(System.ReadOnlySpan<byte> first, System.ReadOnlySpan<char> second) -> bool
4-
[SER004]static RESPite.AsciiHash.EqualsCI(System.ReadOnlySpan<char> first, System.ReadOnlySpan<byte> second) -> bool
5-
[SER004]static RESPite.AsciiHash.SequenceEqualsCI(System.ReadOnlySpan<byte> first, System.ReadOnlySpan<char> second) -> bool
6-
[SER004]static RESPite.AsciiHash.SequenceEqualsCI(System.ReadOnlySpan<char> first, System.ReadOnlySpan<byte> second) -> bool
7-
[SER004]virtual RESPite.Buffers.CycleBufferPool<T>.Rent(in System.Buffers.ReadOnlySequence<T> existing) -> System.Buffers.IMemoryOwner<T>!
8-
[SER004]RESPite.Buffers.CycleBuffer.Pool.get -> System.Buffers.MemoryPool<byte>!
9-
[SER004]RESPite.Buffers.CycleBufferPool<T>
10-
[SER004]RESPite.Buffers.CycleBufferPool<T>.CycleBufferPool() -> void
11-
[SER004]static RESPite.Buffers.CycleBuffer.Create(System.Buffers.MemoryPool<byte>? pool = null, RESPite.Buffers.ICycleBufferCallback? callback = null) -> RESPite.Buffers.CycleBuffer
1+
#nullable enable

src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,3 +2517,26 @@ virtual StackExchange.Redis.Configuration.DefaultOptionsProvider.TcpKeepAlive.ge
25172517
[SER006]StackExchange.Redis.ArrayInfo.ArrayInfo(scoped System.ReadOnlySpan<System.Collections.Generic.KeyValuePair<string!, StackExchange.Redis.RedisValue>> values) -> void
25182518
[SER006]StackExchange.Redis.ArrayInfo.ToDictionary() -> System.Collections.Generic.Dictionary<string!, StackExchange.Redis.RedisValue>!
25192519
[SER006]StackExchange.Redis.ArrayInfo.this[string! key].get -> StackExchange.Redis.RedisValue
2520+
StackExchange.Redis.ConfigurationOptions.RequestBufferPool.get -> System.Buffers.MemoryPool<byte>?
2521+
StackExchange.Redis.ConfigurationOptions.RequestBufferPool.set -> void
2522+
StackExchange.Redis.ConfigurationOptions.ResponseBufferPool.get -> System.Buffers.MemoryPool<byte>?
2523+
StackExchange.Redis.ConfigurationOptions.ResponseBufferPool.set -> void
2524+
static StackExchange.Redis.Lease<T>.Create(int length, System.Buffers.MemoryPool<T>? pool, bool clear = true) -> StackExchange.Redis.Lease<T>!
2525+
[SER005]StackExchange.Redis.TestHarness
2526+
[SER005]StackExchange.Redis.TestHarness.BufferValidator
2527+
[SER005]StackExchange.Redis.TestHarness.ChannelPrefix.get -> StackExchange.Redis.RedisChannel
2528+
[SER005]StackExchange.Redis.TestHarness.CommandMap.get -> StackExchange.Redis.CommandMap!
2529+
[SER005]StackExchange.Redis.TestHarness.KeyPrefix.get -> StackExchange.Redis.RedisKey
2530+
[SER005]StackExchange.Redis.TestHarness.Read(System.ReadOnlySpan<byte> value) -> StackExchange.Redis.RedisResult!
2531+
[SER005]StackExchange.Redis.TestHarness.TestHarness(StackExchange.Redis.CommandMap? commandMap = null, StackExchange.Redis.RedisChannel channelPrefix = default(StackExchange.Redis.RedisChannel), StackExchange.Redis.RedisKey keyPrefix = default(StackExchange.Redis.RedisKey)) -> void
2532+
[SER005]StackExchange.Redis.TestHarness.ValidateResp(System.ReadOnlySpan<byte> expected, string! command, params System.Collections.Generic.ICollection<object!>! args) -> void
2533+
[SER005]StackExchange.Redis.TestHarness.ValidateResp(string! expected, string! command, params System.Collections.Generic.ICollection<object!>! args) -> void
2534+
[SER005]StackExchange.Redis.TestHarness.ValidateRouting(in StackExchange.Redis.RedisKey expected, params System.Collections.Generic.ICollection<object!>! args) -> void
2535+
[SER005]StackExchange.Redis.TestHarness.Write(System.Buffers.IBufferWriter<byte>! target, string! command, params System.Collections.Generic.ICollection<object!>! args) -> void
2536+
[SER005]StackExchange.Redis.TestHarness.Write(string! command, params System.Collections.Generic.ICollection<object!>! args) -> byte[]!
2537+
[SER005]static StackExchange.Redis.TestHarness.AssertEqual(System.ReadOnlySpan<byte> expected, System.ReadOnlySpan<byte> actual, System.Action<System.ReadOnlyMemory<byte>, System.ReadOnlyMemory<byte>>! handler) -> void
2538+
[SER005]static StackExchange.Redis.TestHarness.AssertEqual(string! expected, System.ReadOnlySpan<byte> actual, System.Action<string!, string!>! handler) -> void
2539+
[SER005]virtual StackExchange.Redis.TestHarness.BufferValidator.Invoke(scoped System.ReadOnlySpan<byte> buffer) -> void
2540+
[SER005]virtual StackExchange.Redis.TestHarness.OnValidateFail(System.ReadOnlyMemory<byte> expected, System.ReadOnlyMemory<byte> actual) -> void
2541+
[SER005]virtual StackExchange.Redis.TestHarness.OnValidateFail(in StackExchange.Redis.RedisKey expected, in StackExchange.Redis.RedisKey actual) -> void
2542+
[SER005]virtual StackExchange.Redis.TestHarness.OnValidateFail(string! expected, string! actual) -> void

src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#nullable enable
1+
#nullable enable
22
StackExchange.Redis.ConfigurationOptions.RequestBufferPool.get -> System.Buffers.MemoryPool<byte>?
33
StackExchange.Redis.ConfigurationOptions.RequestBufferPool.set -> void
44
StackExchange.Redis.ConfigurationOptions.ResponseBufferPool.get -> System.Buffers.MemoryPool<byte>?

tests/StackExchange.Redis.Tests/ClusterTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ public async Task TestIdentity()
146146
[Fact]
147147
public async Task IntentionalWrongServer()
148148
{
149+
SkipOnWindowsRelease();
149150
static string? StringGet(IServer server, RedisKey key, CommandFlags flags = CommandFlags.None)
150151
=> (string?)server.Execute(0, "GET", [key], flags);
151152

tests/StackExchange.Redis.Tests/KeyIdleAsyncTests.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,35 @@ namespace StackExchange.Redis.Tests;
88
[RunPerProtocol]
99
public class KeyIdleAsyncTests(ITestOutputHelper output, SharedConnectionFixture fixture) : TestBase(output, fixture)
1010
{
11+
// Target the standalone secure server (6381) rather than the default primary (6379).
12+
// OBJECT IDLETIME is reset via the value's LRU access clock, but Redis deliberately
13+
// suppresses that update while a save/AOF/replication-sync child is active (copy-on-write
14+
// avoidance). The default primary has a replica attached, and every replica full-sync forks
15+
// such a child; if one overlaps a touch/read in these tests, the idle time isn't reset and the
16+
// test flakes (observed on Windows CI). 6381 has no replica and no persistence, so no fork ever
17+
// suppresses the reset and the behaviour is deterministic. Overriding GetConfiguration here also
18+
// opts these tests out of the shared connection fixture, giving each a dedicated 6381 connection.
19+
protected override string GetConfiguration()
20+
=> TestConfig.Current.SecureServerAndPort + ",password=" + TestConfig.Current.SecurePassword;
21+
1122
[Fact]
1223
public async Task IdleTimeAsync()
1324
{
25+
SkipOnWindowsRelease("WSL exacerbates replication time");
1426
await using var conn = Create();
1527

1628
RedisKey key = Me();
1729
var db = conn.GetDatabase();
1830
db.KeyDelete(key, CommandFlags.FireAndForget);
1931
db.StringSet(key, "new value", flags: CommandFlags.FireAndForget);
32+
var timer = Stopwatch.StartNew();
2033
await Task.Delay(2000).ForAwait();
2134
var idleTime = await db.KeyIdleTimeAsync(key).ForAwait();
22-
Assert.True(idleTime > TimeSpan.Zero, "First check");
35+
Assert.True(idleTime > TimeSpan.Zero, $"First check: {idleTime} should be > 0; elapsed: {timer.ElapsedMilliseconds}ms");
2336

2437
db.StringSet(key, "new value2", flags: CommandFlags.FireAndForget);
2538
var idleTime2 = await db.KeyIdleTimeAsync(key).ForAwait();
26-
Assert.True(idleTime2 < idleTime, "Second check");
39+
Assert.True(idleTime2 < idleTime, $"Second check: {idleTime2} should be < {idleTime}; elapsed: {timer.ElapsedMilliseconds}ms");
2740

2841
db.KeyDelete(key);
2942
var idleTime3 = await db.KeyIdleTimeAsync(key).ForAwait();
@@ -33,6 +46,7 @@ public async Task IdleTimeAsync()
3346
[Fact]
3447
public async Task TouchIdleTimeAsync()
3548
{
49+
SkipOnWindowsRelease("WSL exacerbates replication time");
3650
await using var conn = Create(require: RedisFeatures.v3_2_1);
3751

3852
RedisKey key = Me();
Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23
using System.Threading.Tasks;
34
using Xunit;
45

@@ -7,22 +8,35 @@ namespace StackExchange.Redis.Tests;
78
[RunPerProtocol]
89
public class KeyIdleTests(ITestOutputHelper output, SharedConnectionFixture fixture) : TestBase(output, fixture)
910
{
11+
// Target the standalone secure server (6381) rather than the default primary (6379).
12+
// OBJECT IDLETIME is reset via the value's LRU access clock, but Redis deliberately
13+
// suppresses that update while a save/AOF/replication-sync child is active (copy-on-write
14+
// avoidance). The default primary has a replica attached, and every replica full-sync forks
15+
// such a child; if one overlaps a touch/read in these tests, the idle time isn't reset and the
16+
// test flakes (observed on Windows CI). 6381 has no replica and no persistence, so no fork ever
17+
// suppresses the reset and the behaviour is deterministic. Overriding GetConfiguration here also
18+
// opts these tests out of the shared connection fixture, giving each a dedicated 6381 connection.
19+
protected override string GetConfiguration()
20+
=> TestConfig.Current.SecureServerAndPort + ",password=" + TestConfig.Current.SecurePassword;
21+
1022
[Fact]
1123
public async Task IdleTime()
1224
{
25+
SkipOnWindowsRelease("WSL exacerbates replication time");
1326
await using var conn = Create();
1427

1528
RedisKey key = Me();
1629
var db = conn.GetDatabase();
1730
db.KeyDelete(key, CommandFlags.FireAndForget);
1831
db.StringSet(key, "new value", flags: CommandFlags.FireAndForget);
32+
var timer = Stopwatch.StartNew();
1933
await Task.Delay(2000).ForAwait();
2034
var idleTime = db.KeyIdleTime(key);
21-
Assert.True(idleTime > TimeSpan.Zero);
35+
Assert.True(idleTime > TimeSpan.Zero, $"First check: {idleTime} should be > 0; elapsed: {timer.ElapsedMilliseconds}ms");
2236

2337
db.StringSet(key, "new value2", flags: CommandFlags.FireAndForget);
2438
var idleTime2 = db.KeyIdleTime(key);
25-
Assert.True(idleTime2 < idleTime);
39+
Assert.True(idleTime2 < idleTime, $"Second check: {idleTime2} should be < {idleTime}; elapsed: {timer.ElapsedMilliseconds}ms");
2640

2741
db.KeyDelete(key);
2842
var idleTime3 = db.KeyIdleTime(key);
@@ -32,18 +46,20 @@ public async Task IdleTime()
3246
[Fact]
3347
public async Task TouchIdleTime()
3448
{
49+
SkipOnWindowsRelease("WSL exacerbates replication time");
3550
await using var conn = Create(require: RedisFeatures.v3_2_1);
3651

3752
RedisKey key = Me();
3853
var db = conn.GetDatabase();
3954
db.KeyDelete(key, CommandFlags.FireAndForget);
4055
db.StringSet(key, "new value", flags: CommandFlags.FireAndForget);
56+
var timer = Stopwatch.StartNew();
4157
await Task.Delay(2000).ForAwait();
4258
var idleTime = db.KeyIdleTime(key);
43-
Assert.True(idleTime > TimeSpan.Zero, "First check");
59+
Assert.True(idleTime > TimeSpan.Zero, $"First check: {idleTime} should be > 0; elapsed: {timer.ElapsedMilliseconds}ms");
4460

45-
Assert.True(db.KeyTouch(key), "Second check");
61+
Assert.True(db.KeyTouch(key), $"Second check: should be True; elapsed: {timer.ElapsedMilliseconds}ms");
4662
var idleTime1 = db.KeyIdleTime(key);
47-
Assert.True(idleTime1 < idleTime, "Third check");
63+
Assert.True(idleTime1 < idleTime, $"Third check: {idleTime1} should be < {idleTime}; elapsed: {timer.ElapsedMilliseconds}ms");
4864
}
4965
}

tests/StackExchange.Redis.Tests/RoleTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class Roles(ITestOutputHelper output, SharedConnectionFixture fixture) :
1313
[InlineData(false)]
1414
public async Task PrimaryRole(bool allowAdmin) // should work with or without admin now
1515
{
16+
SkipOnWindowsRelease();
1617
await using var conn = Create(allowAdmin: allowAdmin);
1718
var servers = conn.GetServers();
1819
Log("Server list:");

0 commit comments

Comments
 (0)