Initial version
This commit is contained in:
220
README.md
220
README.md
@@ -1,3 +1,219 @@
|
||||
# EonaCat.DeterministicTime
|
||||
# EonaCat.DeterministicTime
|
||||
|
||||
EonaCat.DeterministicTime is a **.NET library for deterministic, testable, and replayable time**.
|
||||
|
||||
It replaces `DateTime.UtcNow`, `Stopwatch`, `Timer`, and `Task.Delay` with deterministic equivalents and supports advanced features like:
|
||||
|
||||
scheduling,
|
||||
time scaling,
|
||||
replay,
|
||||
NTP offsets,
|
||||
ASP.NET Framework integration.
|
||||
ASP.NET Core integration.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
dotnet add package EonaCat.DeterministicTime
|
||||
```
|
||||
|
||||
|
||||
### ASP.NET Core integration (optional)
|
||||
|
||||
```
|
||||
dotnet add package DeterministicTime.AspNetCore
|
||||
```
|
||||
|
||||
### ASP.NET Framework integration (optional)
|
||||
|
||||
```
|
||||
dotnet add package DeterministicTime.AspNetFramework
|
||||
```
|
||||
|
||||
ASP.NET 4.8 → add DeterministicTime.AspNetFramework and register HttpModule in web.config:
|
||||
```xml
|
||||
<system.web>
|
||||
<httpModules>
|
||||
<add name="DeterministicTime" type="DeterministicTimeHttpModule"/>
|
||||
</httpModules>
|
||||
</system.web>
|
||||
```
|
||||
|
||||
---
|
||||
## Basic Usage
|
||||
|
||||
```csharp
|
||||
using DeterministicTime;
|
||||
|
||||
DateTime now = DeterministicTime.UtcNow;
|
||||
DateTime localNow = DeterministicTime.Now;
|
||||
```
|
||||
|
||||
---
|
||||
## Freeze Time
|
||||
|
||||
```csharp
|
||||
using (TimeScope.Frozen(DateTime.Parse("2025-01-01T00:00:00Z")))
|
||||
{
|
||||
Console.WriteLine(DeterministicTime.UtcNow); // frozen
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
## Scale Time
|
||||
|
||||
```csharp
|
||||
using (TimeScope.Scaled(10)) // 10x faster
|
||||
{
|
||||
// all timers and delays scale 10x
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advance Time Manually
|
||||
|
||||
```csharp
|
||||
DeterministicTime.Advance(TimeSpan.FromHours(2));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Offset Time
|
||||
|
||||
```csharp
|
||||
using (TimeScope.Offset(TimeSpan.FromMinutes(5)))
|
||||
{
|
||||
// all UtcNow calls are offset by 5 minutes
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deterministic Stopwatch
|
||||
|
||||
```csharp
|
||||
var sw = DeterministicStopwatch.StartNew();
|
||||
// do work
|
||||
sw.Stop();
|
||||
Console.WriteLine(sw.Elapsed);
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Deterministic Timer
|
||||
|
||||
```csharp
|
||||
int fired = 0;
|
||||
DeterministicTimer.Start(TimeSpan.FromSeconds(10), () => fired++);
|
||||
DeterministicTime.Advance(TimeSpan.FromSeconds(10));
|
||||
Console.WriteLine(fired); // 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deterministic Delay
|
||||
|
||||
```csharp
|
||||
bool completed = false;
|
||||
await DeterministicDelay.For(TimeSpan.FromSeconds(5)).ContinueWith(_ => completed = true);
|
||||
DeterministicTime.Advance(TimeSpan.FromSeconds(5));
|
||||
Console.WriteLine(completed); // true
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Deterministic Scheduler
|
||||
|
||||
```csharp
|
||||
var scheduler = DeterministicScheduler.Global;
|
||||
scheduler.Every(TimeSpan.FromMinutes(1), () => Console.WriteLine("Tick"));
|
||||
DeterministicTime.Advance(TimeSpan.FromMinutes(5)); // fires 5 times
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Time Recording & Replay
|
||||
|
||||
### Record
|
||||
|
||||
```csharp
|
||||
using var recording = TimeRecording.Start();
|
||||
// run code
|
||||
recording.Save("run.json");
|
||||
```
|
||||
|
||||
### Replay
|
||||
|
||||
```csharp
|
||||
using (TimeReplay.Load("run.json"))
|
||||
{
|
||||
// deterministic replay of UtcNow calls
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## NTP Synchronization
|
||||
|
||||
```csharp
|
||||
using (NtpSynchronization.Sync(myNtpProvider))
|
||||
{
|
||||
// deterministic time aligned with NTP
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Distributed Time Source
|
||||
|
||||
```csharp
|
||||
IDistributedTimeCoordinator coordinator = ...;
|
||||
DeterministicTime.Push(new DistributedTimeSource(coordinator));
|
||||
Console.WriteLine(DeterministicTime.UtcNow);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ASP.NET Core Middleware
|
||||
|
||||
```csharp
|
||||
app.UseDeterministicTime();
|
||||
```
|
||||
|
||||
* Each request runs in its own deterministic scope
|
||||
|
||||
* Works with frozen/scaled time and timers
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Advanced Features Summary
|
||||
|
||||
* **Deterministic UtcNow & Now**
|
||||
|
||||
* **Stopwatch replacement**
|
||||
|
||||
* **One-shot and repeated timers**
|
||||
|
||||
* **Task.Delay replacement**
|
||||
|
||||
* **Time scaling, freezing, offset**
|
||||
|
||||
* **Scheduler for background jobs**
|
||||
|
||||
* **Recording & replay for testing**
|
||||
|
||||
* **NTP synchronization & distributed clocks**
|
||||
|
||||
* **ASP.NET Framework integration**
|
||||
|
||||
* **ASP.NET Core integration**
|
||||
|
||||
|
||||
EonaCat.DeterministicTime
|
||||
Reference in New Issue
Block a user