NServiceBus/NServiceBus — pull request #1351 by tkristiansen (2013-07-27 17:26:07+00:00)
Title: Time simulation feature

We have implemented a time simulation feature in our ongoing project. It lets us run business processes that normally last for weeks in just a few minutes and still showing "proper" dates. The way we do this, is by never using DateTime.Now, but always use an IClock interface that has a single property: Now.

As default there is a SystemClock (which Now returns DateTime.Now). When simulation is activated, we replace the system clock with a simulation clock.

The simulated clock always has a virtual time and a real time. Normally we start the simulation with both times being Now, and then the virtual time would be maybe a thousand times faster than the real time.

To activate the simulation, we just configure it on our "developer panel" in the UI and all commands executed as long as it is active are tagged with a header identifying the simulation context.
The settings for the context are stored in a database, and all messages sent while the given context is active will maintain the simulation header so that the simulation module can load them before the messages are being handled.

Since we want deferred messages to obey the simulation, we had to wrap the UnicastBus in order to let Defer work properly. Defer is always called with the virtual time (none of our business components knows the simulation concept), but as long as the simulation is active, we translate the virtual time to the real time in order to get the message delivered in a few seconds/minutes instead of hours/days.

This is the essence of what our wrapper does:

```
public new ICallback Defer(DateTime virtualTime, params object[] messages)
{
DateTime realTime;
if (_simulation.IsActive)
{
realTime = _simulation.VirtualToReal(virtualTime);
NServiceBusSimulationIntegration.SetTimeoutMessageHeader(messages.First(), virtualTime);
}
else
{
realTime = virtualTime;
}
return _bus.Defer(realTime, messages);
}
```

Now I have two questions:

1. Does the community have interest in such a feature, and is it something that is wanted as a feature in NSB?
2. Would you be willing to at least adopt the IClock interface and use it inside NSB? As far as I can tell it is a 100 % non-breaking and binary compatible change...
That way we could get rid of our ugly wrapper, and it would open up for easily making such a simulation concept even if it is not a part of NSB (could be a contrib or sample).

We could help making the necessary changes - at least introducing IClock. The full simulation concept is a bit heavier and also depends a bit on the rest of our infrastructure, so I guess it should at least be discussed before it is integrated. It might suit better as a sample.