org.glassfish.jersey.server.internal.monitoring.TimeWindowStatisticsImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jersey-server Show documentation
Show all versions of jersey-server Show documentation
Jersey core server implementation
/*
* Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.jersey.server.internal.monitoring;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.glassfish.jersey.server.internal.monitoring.core.TimeReservoir;
import org.glassfish.jersey.server.internal.monitoring.core.UniformTimeSnapshot;
import org.glassfish.jersey.server.monitoring.TimeWindowStatistics;
/**
* Immutable {@link TimeWindowStatistics Time window statistics} that uses backing {@link SlidingWindowTimeReservoir} for its
* {@code Builder} implementation.
*
* @author Miroslav Fuksa
* @author Stepan Vavra
*/
final class TimeWindowStatisticsImpl implements TimeWindowStatistics {
/**
* Builder of time window statistics.
*/
static class Builder {
/**
* Total interval for which these statistics are calculated (eg. last 15 seconds, last one minute) converted to ms
*/
private final long interval;
private final TimeReservoir timeReservoir;
/**
* Create new time window statistics builder instance.
*
* @param timeReservoir statistically representative reservoir of long values data stream in time.
*/
Builder(TimeReservoir timeReservoir) {
interval = timeReservoir.interval(TimeUnit.MILLISECONDS);
this.timeReservoir = timeReservoir;
}
/**
* Add request execution.
*
* @param requestTime Time of execution.
* @param duration Duration of request processing.
*/
void addRequest(final long requestTime, final V duration) {
timeReservoir.update(duration, requestTime, TimeUnit.MILLISECONDS);
}
/**
* Build the time window statistics instance.
*
* @return New instance of statistics.
*/
TimeWindowStatisticsImpl build() {
return build(System.currentTimeMillis());
}
/**
* Build the time window statistics instance.
*
* @param currentTime Current time as a reference to which the statistics should be built.
* @return New instance of statistics.
*/
TimeWindowStatisticsImpl build(final long currentTime) {
final UniformTimeSnapshot durationReservoirSnapshot = timeReservoir
.getSnapshot(currentTime, TimeUnit.MILLISECONDS);
// if nothing was collected, return a single empty stat instance
if (durationReservoirSnapshot.size() == 0) {
return getOrCreateEmptyStats(interval);
}
return new TimeWindowStatisticsImpl(interval, durationReservoirSnapshot);
}
private TimeWindowStatisticsImpl getOrCreateEmptyStats(final long interval) {
if (!EMPTY.containsKey(interval)) {
EMPTY.putIfAbsent(interval, new TimeWindowStatisticsImpl(interval, 0, -1, -1, -1, 0));
}
return EMPTY.get(interval);
}
public long getInterval() {
return interval;
}
}
private static final ConcurrentHashMap EMPTY = new ConcurrentHashMap<>(6);
static {
EMPTY.putIfAbsent(0L, new TimeWindowStatisticsImpl(0, 0, 0, 0, 0, 0));
}
private final long interval;
private final long minimumDuration;
private final long maximumDuration;
private final long averageDuration;
private final long totalCount;
private final double requestsPerSecond;
private TimeWindowStatisticsImpl(final long interval, final double requestsPerSecond, final long minimumDuration,
final long maximumDuration, final long averageDuration, final long totalCount) {
this.interval = interval;
this.requestsPerSecond = requestsPerSecond;
this.minimumDuration = minimumDuration;
this.maximumDuration = maximumDuration;
this.averageDuration = averageDuration;
this.totalCount = totalCount;
}
private TimeWindowStatisticsImpl(final long interval, final UniformTimeSnapshot snapshot) {
this(interval, snapshot.getRate(TimeUnit.SECONDS), snapshot.getMin(), snapshot.getMax(), (long) snapshot.getMean(),
snapshot.size());
}
@Override
public long getTimeWindow() {
return interval;
}
@Override
public double getRequestsPerSecond() {
return requestsPerSecond;
}
@Override
public long getMinimumDuration() {
return minimumDuration;
}
@Override
public long getMaximumDuration() {
return maximumDuration;
}
@Override
public long getRequestCount() {
return totalCount;
}
@Override
public TimeWindowStatistics snapshot() {
// TimeWindowStatisticsImpl is immutable; the Builder is mutable
return this;
}
@Override
public long getAverageDuration() {
return averageDuration;
}
}