Package com.graphaware.runtime.schedule

Source Code of com.graphaware.runtime.schedule.AdaptiveTimingStrategy

package com.graphaware.runtime.schedule;

import com.graphaware.runtime.monitor.DatabaseLoadMonitor;
import com.graphaware.runtime.monitor.RunningWindowAverage;
import com.graphaware.runtime.monitor.StartedTxBasedLoadMonitor;
import org.neo4j.graphdb.GraphDatabaseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Implementation of {@link TimingStrategy} that pays attention to the current level of activity in the database, i.e.
* the number of started transactions, in order to decide how long to wait before scheduling the next task.
*/
public class AdaptiveTimingStrategy implements TimingStrategy {

    private final long delta;
    private final long defaultDelay;
    private final long minDelay;
    private final long maxDelay;
    private final long busyThreshold;
    private final int maxSamples;
    private final int maxTime;

    private DelayAdjuster delayAdjuster;
    private DatabaseLoadMonitor loadMonitor;

    private long previousDelay = UNKNOWN;

    /**
     * Create a new instance of this strategy with default configuration, which is:
     * <ul>
     * <li>delta = 100ms</li>
     * <li>default delay = 2s</li>
     * <li>minimum delay = 5ms</li>
     * <li>maximum delay = 10s</li>
     * <li>busy threshold = 100</li>
     * <li>maximum samples = 200</li>
     * <li>maximum time = 2s</li>
     * </ul>
     *
     * @return instance of this strategy.
     */
    public static AdaptiveTimingStrategy defaultConfiguration() {
        return new AdaptiveTimingStrategy(100, 2_000, 5, 5_000, 100, 200, 2_000);
    }

    /**
     * Constructs a new instance of this strategy with the specified configuration settings.
     *
     * @param delta         The number of milliseconds by which to adjust the current delay.
     * @param defaultDelay  The number of milliseconds to return if there is not enough information to make a better decision.
     * @param minDelay      The lower limit to the delay that can be returned as the next delay.
     * @param maxDelay      The upper limit to the delay that can be returned as the next delay.
     * @param busyThreshold The number of transactions per second, above which the database is deemed
     *                      to be busy.
     * @param maxSamples    The maximum number of running window average samples. See {@link RunningWindowAverage}.
     * @param maxTime       The maximum amount of running window average time. See {@link RunningWindowAverage}.
     */
    private AdaptiveTimingStrategy(long delta, long defaultDelay, long minDelay, long maxDelay, long busyThreshold, int maxSamples, int maxTime) {
        this.delta = delta;
        this.defaultDelay = defaultDelay;
        this.minDelay = minDelay;
        this.maxDelay = maxDelay;
        this.busyThreshold = busyThreshold;
        this.maxSamples = maxSamples;
        this.maxTime = maxTime;
    }

    /**
     * Returns a copy of this {@link AdaptiveTimingStrategy} reconfigured to use the specified delta.
     *
     * @param delta The new delta in milliseconds.
     * @return A new {@link AdaptiveTimingStrategy}.
     */
    public AdaptiveTimingStrategy withDelta(long delta) {
        return new AdaptiveTimingStrategy(delta, this.defaultDelay, this.minDelay, this.maxDelay, this.busyThreshold, this.maxSamples, this.maxTime);
    }

    /**
     * Returns a copy of this {@link AdaptiveTimingStrategy} reconfigured to use the specified default timer-driven
     * module scheduling delay.
     *
     * @param defaultDelay The new default scheduling delay in milliseconds.
     * @return A new {@link AdaptiveTimingStrategy}.
     */
    public AdaptiveTimingStrategy withDefaultDelayMillis(long defaultDelay) {
        return new AdaptiveTimingStrategy(this.delta, defaultDelay, this.minDelay, this.maxDelay, this.busyThreshold, this.maxSamples, this.maxTime);
    }

    /**
     * Returns a copy of this {@link AdaptiveTimingStrategy} reconfigured to use the specified minimum delay between
     * timer-driven module invocations.
     *
     * @param minDelay The new minimum delay between timer-driven module invocations.
     * @return A new {@link AdaptiveTimingStrategy}.
     */
    public AdaptiveTimingStrategy withMinimumDelayMillis(long minDelay) {
        return new AdaptiveTimingStrategy(this.delta, this.defaultDelay, minDelay, this.maxDelay, this.busyThreshold, this.maxSamples, this.maxTime);
    }

    /**
     * Returns a copy of this {@link AdaptiveTimingStrategy} reconfigured to use the specified maximum delay between
     * timer-driven module invocations.
     *
     * @param maxDelay The new maximum delay between timer-driven module invocations.
     * @return A new {@link AdaptiveTimingStrategy}.
     */
    public AdaptiveTimingStrategy withMaximumDelayMillis(long maxDelay) {
        return new AdaptiveTimingStrategy(this.delta, this.defaultDelay, this.minDelay, maxDelay, this.busyThreshold, this.maxSamples, this.maxTime);
    }

    /**
     * Returns a copy of this {@link AdaptiveTimingStrategy} reconfigured to use the given busy threshold.
     *
     * @param busyThreshold The new busy threshold to use.
     * @return A new {@link AdaptiveTimingStrategy}.
     */
    public AdaptiveTimingStrategy withBusyThreshold(int busyThreshold) {
        return new AdaptiveTimingStrategy(this.delta, this.defaultDelay, this.minDelay, this.maxDelay, busyThreshold, this.maxSamples, this.maxTime);
    }

    /**
     * Returns a copy of this {@link AdaptiveTimingStrategy} reconfigured to use the maximum number of samples.
     *
     * @param maxSamples The new maximum number of samples to use.
     * @return A new {@link AdaptiveTimingStrategy}.
     */
    public AdaptiveTimingStrategy withMaxSamples(int maxSamples) {
        return new AdaptiveTimingStrategy(this.delta, this.defaultDelay, this.minDelay, this.maxDelay, this.busyThreshold, maxSamples, this.maxTime);
    }

    /**
     * Returns a copy of this {@link AdaptiveTimingStrategy} reconfigured to use the given maximum running average window time span.
     *
     * @param maxTime The new maximum time to use.
     * @return A new {@link AdaptiveTimingStrategy}.
     */
    public AdaptiveTimingStrategy withMaxTime(int maxTime) {
        return new AdaptiveTimingStrategy(this.delta, this.defaultDelay, this.minDelay, this.maxDelay, this.busyThreshold, this.maxSamples, maxTime);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void initialize(GraphDatabaseService database) {
        this.delayAdjuster = new ConstantDeltaDelayAdjuster(this.delta, this.defaultDelay, this.minDelay, this.maxDelay, this.busyThreshold);
        this.loadMonitor = new StartedTxBasedLoadMonitor(database, new RunningWindowAverage(this.maxSamples, this.maxTime));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public long nextDelay(long lastTaskDuration) {
        if (delayAdjuster == null || loadMonitor == null) {
            throw new IllegalStateException("Initialization hasn't been performed, this is a bug.");
        }

        long newDelay = delayAdjuster.determineNextDelay(previousDelay, lastTaskDuration, loadMonitor.getLoad());

        previousDelay = newDelay;

        return newDelay;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AdaptiveTimingStrategy that = (AdaptiveTimingStrategy) o;

        if (busyThreshold != that.busyThreshold) return false;
        if (defaultDelay != that.defaultDelay) return false;
        if (delta != that.delta) return false;
        if (maxDelay != that.maxDelay) return false;
        if (maxSamples != that.maxSamples) return false;
        if (maxTime != that.maxTime) return false;
        if (minDelay != that.minDelay) return false;

        return true;
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        int result = (int) (delta ^ (delta >>> 32));
        result = 31 * result + (int) (defaultDelay ^ (defaultDelay >>> 32));
        result = 31 * result + (int) (minDelay ^ (minDelay >>> 32));
        result = 31 * result + (int) (maxDelay ^ (maxDelay >>> 32));
        result = 31 * result + (int) (busyThreshold ^ (busyThreshold >>> 32));
        result = 31 * result + maxSamples;
        result = 31 * result + maxTime;
        return result;
    }
}
TOP

Related Classes of com.graphaware.runtime.schedule.AdaptiveTimingStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.