-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Heartbeat interval: Make it configurable (#2243)
When I was looking at a separate timer for async timeout evaluation < 1000ms fidelity it became apparent most of the cost in a heartbeat is the timeout evaluation anyway, but also: if you are chasing a lower timeout fidelity you likely want to observe a server outage ASAP as well so I think it makes more sense to actually open up the heartbeat to make it configurable. I added some docs about how this is risky but that portion and comments could use scrutiny (if we even agree with doing this) on being strong enough warnings around this. I would prefer to leave this as code-only due to potential downsides people may not appreciate otherwise.
- Loading branch information
1 parent
5ceb775
commit d1b802b
Showing
8 changed files
with
98 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace StackExchange.Redis.Tests; | ||
|
||
[Collection(NonParallelCollection.Name)] | ||
public class CommandTimeouts : TestBase | ||
{ | ||
public CommandTimeouts(ITestOutputHelper output) : base (output) { } | ||
|
||
[Fact] | ||
public async Task DefaultHeartbeatTimeout() | ||
{ | ||
var options = ConfigurationOptions.Parse(TestConfig.Current.PrimaryServerAndPort); | ||
options.AllowAdmin = true; | ||
options.AsyncTimeout = 1000; | ||
|
||
using var pauseConn = ConnectionMultiplexer.Connect(options); | ||
using var conn = ConnectionMultiplexer.Connect(options); | ||
|
||
var pauseServer = GetServer(pauseConn); | ||
_ = pauseServer.ExecuteAsync("CLIENT", "PAUSE", 2000); | ||
|
||
var key = Me(); | ||
var db = conn.GetDatabase(); | ||
var sw = ValueStopwatch.StartNew(); | ||
var ex = await Assert.ThrowsAsync<RedisTimeoutException>(async () => await db.StringGetAsync(key)); | ||
Log(ex.Message); | ||
var duration = sw.GetElapsedTime(); | ||
Assert.True(duration < TimeSpan.FromSeconds(2100), $"Duration ({duration.Milliseconds} ms) should be less than 2100ms"); | ||
} | ||
|
||
[Fact] | ||
public async Task DefaultHeartbeatLowTimeout() | ||
{ | ||
var options = ConfigurationOptions.Parse(TestConfig.Current.PrimaryServerAndPort); | ||
options.AllowAdmin = true; | ||
options.AsyncTimeout = 50; | ||
options.HeartbeatInterval = TimeSpan.FromMilliseconds(100); | ||
|
||
using var pauseConn = ConnectionMultiplexer.Connect(options); | ||
using var conn = ConnectionMultiplexer.Connect(options); | ||
|
||
var pauseServer = GetServer(pauseConn); | ||
_ = pauseServer.ExecuteAsync("CLIENT", "PAUSE", 2000); | ||
|
||
var key = Me(); | ||
var db = conn.GetDatabase(); | ||
var sw = ValueStopwatch.StartNew(); | ||
var ex = await Assert.ThrowsAsync<RedisTimeoutException>(async () => await db.StringGetAsync(key)); | ||
Log(ex.Message); | ||
var duration = sw.GetElapsedTime(); | ||
Assert.True(duration < TimeSpan.FromSeconds(250), $"Duration ({duration.Milliseconds} ms) should be less than 250ms"); | ||
} | ||
} |