All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.browsermob.proxy.util.BandwidthSimulator Maven / Gradle / Ivy

There is a newer version: 2.0-beta-7
Show newest version
package org.browsermob.proxy.util;

public class BandwidthSimulator {
    // Too large and the instantaneous bandwidth varies too much.
    // Too small and we don't reach the target fast enough.
    private static final float DAMPING_FACTOR = 0.5f;

    private long startTime;
    private int sleepTime;
    private float damping;
    private final int targetBps;
    private final int bufferIncrement;

    public BandwidthSimulator(int targetBPS) {
        targetBps = targetBPS;

        // We must use a larger buffer increment for higher BPS rates due to the
        // precision to which we can sleep (maybe ~10ms). Limiting for higher
        // BPS rates will only apply to large messages, but that's not something
        // we can help.
        //
        // I considered adjusting the buffer increment based on the target baud, or
        // dynamically based on the measured performance. I discounted this because
        // there's no obvious algorithm, and its likely to cause non-linear
        // behaviour due to external influences such as the MTU size. Also, having
        // the increment too small will increase the work that we have to do within
        // The Grinder, which might significantly skew timings.
        bufferIncrement = Math.max(100, targetBps / 500);
    }

    public int maximumBytes(int position) {
        if (targetBps == 0) {
            return Integer.MAX_VALUE;
        }

        final long now = System.currentTimeMillis();

        if (position == 0) {
            startTime = now;

            // Set the initial sleep time to 0 so we start pumping bytes straight
            // away.
            sleepTime = 0;

            // Set the second sleep time based on the first lot of bytes transfered.
            // The damping is 2 to account for the initial call.
            damping = 2;
        } else {
            final long expectedTime = (long) position * 8 * 1000 / targetBps;
            final long actualTime = now - startTime;
            sleepTime += (expectedTime - actualTime) * damping;

            if (sleepTime < 0) {
                sleepTime = 0;
            }

            damping = DAMPING_FACTOR;
        }

        try {
            Thread.sleep(sleepTime, 0);
        } catch (InterruptedException e) {
            Thread.interrupted();
        }

        // Allow bufferIncrement bytes to be read.
        return bufferIncrement;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy