Skip to content

Getting Started

Clockworks is a .NET library for deterministic, fully controllable time in distributed-system simulations and tests. It is built around TimeProvider so that time becomes an injectable dependency you can control — including timers and timeouts — while also providing time-ordered identifiers and causal timestamps.

Installation

Install via the .NET CLI:

bash
dotnet add package Clockworks

Or add directly to your project file:

xml
<PackageReference Include="Clockworks" Version="1.3.0" />

Requirements

  • .NET 10.0+ (net10.0 target framework)
  • No additional runtime dependencies

Quick Start

Deterministic timers with simulated time

csharp
var tp = new SimulatedTimeProvider();

var fired = 0;
using var timer = tp.CreateTimer(_ => fired++, null, TimeSpan.FromSeconds(1), Timeout.InfiniteTimeSpan);

tp.Advance(TimeSpan.FromSeconds(1));
// fired == 1

TimeProvider-driven timeouts

csharp
var tp = new SimulatedTimeProvider();

using var timeout = Timeouts.CreateTimeoutHandle(tp, TimeSpan.FromSeconds(5));

tp.Advance(TimeSpan.FromSeconds(5));
// timeout.Token.IsCancellationRequested == true

UUIDv7 generation

csharp
var factory = new UuidV7Factory(TimeProvider.System);
var id = factory.NewGuid();

Dependency injection (ASP.NET Core)

Clockworks includes DI helpers for registering factories and TimeProvider:

csharp
using Clockworks;
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();

// UUIDv7 factory using system time
services.AddLockFreeGuidFactory();

// Or: HLC-based factory (also registers IUuidV7Factory)
services.AddHlcGuidFactory(nodeId: 1, options: HlcOptions.Default);

Vector Clock usage

csharp
// Create coordinators for two nodes
var nodeA = new VectorClockCoordinator(nodeId: 1);
var nodeB = new VectorClockCoordinator(nodeId: 2);

// Node A sends a message
var clockA = nodeA.BeforeSend();

// Node B receives the message
nodeB.BeforeReceive(clockA);

// Node B sends a reply
var clockB = nodeB.BeforeSend();

// Verify causality
Console.WriteLine(clockA.HappensBefore(clockB)); // true

Next Steps

Released under the MIT License.