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

com.kolibrifx.common.clock.LatencyReporter Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2017, KolibriFX AS. Licensed under the Apache License, version 2.0.
 */

package com.kolibrifx.common.clock;

import java.util.function.Consumer;
import java.util.function.LongSupplier;
import com.kolibrifx.common.Safety;

public final class LatencyReporter {
    private static final LongSupplier MILLIS_PROVIDER = () -> System.currentTimeMillis();
    private static final LongSupplier NANOTIME_PROVIDER = () -> System.nanoTime();

    private final LatencyTracker tracker;
    private final int logFrequency;
    private final int resetFrequency;
    private int recordCount = 0;
    private final LongSupplier clockProvider;
    private volatile boolean reporting = false;
    private final Consumer reportListener;

    private LatencyReporter(final LongSupplier clockProvider,
                            final LatencyTracker tracker,
                            final int logFrequency,
                            final int resetFrequency,
                            final Consumer reportListener) {
        this.clockProvider = clockProvider;
        this.logFrequency = logFrequency;
        this.resetFrequency = resetFrequency;
        this.tracker = tracker;
        this.reportListener = reportListener;
        Safety.argumentPositive("logFrequency", logFrequency);
        Safety.argumentPositive("resetFrequency", resetFrequency);
    }

    public void setReporting(final boolean state) {
        reporting = state;
    }

    private void recordImpl(final long startTimestamp, final long endTimestamp) {
        tracker.record(startTimestamp, endTimestamp);
        if (++recordCount == logFrequency) {
            reportListener.accept(tracker.toString());
            recordCount = 0;
        }
        if (tracker.getCount() == resetFrequency) {
            tracker.reset();
        }
    }

    /**
     * Record a data point, getting the end timestamp from the clock provider.
     */
    public void record(final long startTimestamp) {
        if (!reporting) {
            return;
        }
        recordImpl(startTimestamp, clockProvider.getAsLong());
    }

    /**
     * Record a data point, using the given start and end timestamps. Can be used instead of
     * {@link #record(long)} to delay logging after time-critical code has been run.
     */
    public void record(final long startTimestamp, final long endTimestamp) {
        if (!reporting) {
            return;
        }
        recordImpl(startTimestamp, endTimestamp);
    }

    public static LatencyReporter createMillisecondLogger(final String name, final int logFrequency,
                                                          final int resetFrequency, final Consumer consumer,
                                                          final boolean startReporting) {
        final LatencyReporter latencyReporter =
                new LatencyReporter(MILLIS_PROVIDER, new LatencyTracker(name, 1), logFrequency, resetFrequency,
                                    consumer);
        latencyReporter.setReporting(startReporting);
        return latencyReporter;
    }

    public static LatencyReporter createNanosecondLogger(final String name, final int logFrequency,
                                                         final int resetFrequency, final Consumer consumer,
                                                         final boolean startReporting) {
        final LatencyReporter latencyReporter =
                new LatencyReporter(NANOTIME_PROVIDER, new LatencyTracker(name, 1_000_000), logFrequency,
                                    resetFrequency, consumer);
        latencyReporter.setReporting(startReporting);
        return latencyReporter;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy