Date time providersedit
Not typically something you’ll have to pass to the client but all calls to System.DateTime.UtcNow
in the client have been abstracted by IDateTimeProvider. This allows us to unit test timeouts and cluster failover
without being bound to wall clock time as calculated by using System.DateTime.UtcNow directly.
var dateTimeProvider = DateTimeProvider.Default;
dates are always returned in UTC
dateTimeProvider.Now().Should().BeCloseTo(DateTime.UtcNow);
Another responsibility of this interface is to calculate the time a node has to be taken out of rotation based on the number of attempts to revive it. For very advanced use cases, this might be something of interest to provide a custom implementation for.
var dateTimeProvider = DateTimeProvider.Default;
The default timeout calculation is: min(timeout * 2 ^ (attempts * 0.5 -1), maxTimeout), where the
default values for timeout and maxTimeout are
var timeout = TimeSpan.FromMinutes(1); var maxTimeout = TimeSpan.FromMinutes(30);
Plotting these defaults looks as followed:
The goal here is that whenever a node is resurrected and is found to still be offline, we send it back to the doghouse for an ever increasingly long period, until we hit a bounded maximum.
var timeouts = Enumerable.Range(0, 30)
.Select(attempt => dateTimeProvider.DeadTime(attempt, timeout, maxTimeout))
.ToList();
foreach (var increasedTimeout in timeouts.Take(10))
increasedTimeout.Should().BeWithin(maxTimeout);