@Override
    public synchronized void throttle() throws InterruptedException {
        // Run unthrottled if messagesPerWindow is not positive.
        if (messagesPerWindow <= 0) {
            return;
        }

        // Calculate the next window if we've moved beyond the current one.
        if (Time.SYSTEM.milliseconds() >= nextWindowStarts) {
            calculateNextWindow();
        }

        // Increment the message tracker.
        messageTracker += 1;

        // Compare the tracked message count with the throttle limits.
        if (messageTracker >= messagesPerWindow) {

            // Wait the difference in time between now and when the next window starts.
            while (nextWindowStarts > Time.SYSTEM.milliseconds()) {
                wait(nextWindowStarts - Time.SYSTEM.milliseconds());
            }
        }
    }
This throughput generator configures constant throughput.

The lower the window size, the smoother the traffic will be. Using a 100ms window offers no noticeable spikes in
traffic while still being long enough to avoid too much overhead.

Here is an example spec:

{
   "type": "constant",
   "messagesPerWindow": 50,
   "windowSizeMs": 100
}

This will produce a workload that runs 500 messages per second, with a maximum resolution of 50 messages per 100
millisecond.

If `messagesPerWindow` is less than or equal to 0, `throttle` will not throttle at all and will return immediately.
trogdor/src/main/java/org/apache/kafka/trogdor/workload/ConstantThroughputGenerator.java