/*
* Copyright (C) 2015 SoftIndex LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.datakernel.eventloop;
import io.datakernel.jmx.EventStats;
import io.datakernel.jmx.JmxAttribute;
import io.datakernel.jmx.ValueStats;
import java.util.HashMap;
import java.util.Map;
public final class ConcurrentCallsStats {
private final EventStats totalCalls;
private final EventStats rejectedCalls;
private final ValueStats executionDuration;
private final ValueStats awaitingStartDuration;
private double smoothingWindow;
private final Map<String, DistributedStats> taskNameToStats = new HashMap<>();
// region builders
private ConcurrentCallsStats(double smoothingWindow) {
this.smoothingWindow = smoothingWindow;
totalCalls = EventStats.create(smoothingWindow);
rejectedCalls = EventStats.create(smoothingWindow);
executionDuration = ValueStats.create(smoothingWindow);
awaitingStartDuration = ValueStats.create(smoothingWindow);
}
public static ConcurrentCallsStats create(double smoothingWindow) {
return new ConcurrentCallsStats(smoothingWindow);
}
// region builders
public void recordCall(String taskName) {
totalCalls.recordEvent();
ensureConcurrentCallsStatsForTaskName(taskName).getTotalCalls().recordEvent();
}
public void recordRejectedCall(String taskName) {
rejectedCalls.recordEvent();
ensureConcurrentCallsStatsForTaskName(taskName).getRejectedCalls().recordEvent();
}
public void recordCallDuration(String taskName, int duration) {
executionDuration.recordValue(duration);
ensureConcurrentCallsStatsForTaskName(taskName).getExecutionDuration().recordValue(duration);
}
public void recordAwaitingStartDuration(String taskName, int duration) {
awaitingStartDuration.recordValue(duration);
ensureConcurrentCallsStatsForTaskName(taskName).getAwaitingStartDuration().recordValue(duration);
}
@JmxAttribute
public EventStats getTotalCalls() {
return totalCalls;
}
@JmxAttribute
public EventStats getRejectedCalls() {
return rejectedCalls;
}
@JmxAttribute(description = "execution duration of one task (in milliseconds)")
public ValueStats getExecutionDuration() {
return executionDuration;
}
@JmxAttribute(description = "awaiting start duration of one task (in milliseconds)")
public ValueStats getAwaitingStartDuration() {
return awaitingStartDuration;
}
@JmxAttribute
public Map<String, DistributedStats> getTaskNameToStats() {
return taskNameToStats;
}
public static final class DistributedStats {
private final EventStats totalCalls;
private final EventStats rejectedCalls;
private final ValueStats executionDuration;
private final ValueStats awaitingStartDuration;
public DistributedStats(double smoothingWindow) {
totalCalls = EventStats.create(smoothingWindow);
rejectedCalls = EventStats.create(smoothingWindow);
executionDuration = ValueStats.create(smoothingWindow);
awaitingStartDuration = ValueStats.create(smoothingWindow);
}
@JmxAttribute
public EventStats getTotalCalls() {
return totalCalls;
}
@JmxAttribute
public EventStats getRejectedCalls() {
return rejectedCalls;
}
@JmxAttribute
public ValueStats getExecutionDuration() {
return executionDuration;
}
@JmxAttribute
public ValueStats getAwaitingStartDuration() {
return awaitingStartDuration;
}
private void setSmoothingWindow(double smoothingWindow) {
totalCalls.setSmoothingWindow(smoothingWindow);
rejectedCalls.setSmoothingWindow(smoothingWindow);
executionDuration.setSmoothingWindow(smoothingWindow);
awaitingStartDuration.setSmoothingWindow(smoothingWindow);
}
}
private DistributedStats ensureConcurrentCallsStatsForTaskName(String taskName) {
if (!taskNameToStats.containsKey(taskName)) {
DistributedStats stats = new DistributedStats(smoothingWindow);
taskNameToStats.put(taskName, stats);
}
return taskNameToStats.get(taskName);
}
public void setSmoothingWindow(double smoothingWindow) {
this.smoothingWindow = smoothingWindow;
totalCalls.setSmoothingWindow(smoothingWindow);
rejectedCalls.setSmoothingWindow(smoothingWindow);
executionDuration.setSmoothingWindow(smoothingWindow);
awaitingStartDuration.setSmoothingWindow(smoothingWindow);
for (DistributedStats distributedStats : taskNameToStats.values()) {
distributedStats.setSmoothingWindow(smoothingWindow);
}
}
}