/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package co.aikar.timings;
import com.google.common.collect.EvictingQueue;
import net.canarymod.Canary;
import net.canarymod.chat.MessageReceiver;
import net.canarymod.config.Configuration;
import net.canarymod.plugin.Plugin;
import net.canarymod.tasks.ServerTask;
import net.canarymod.tasks.TaskOwner;
import org.neptunepowered.lib.config.TimingsConfiguration;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
public class NeptuneTimingsFactory implements TimingsFactory {
private final int MAX_HISTORY_FRAMES = 12;
public final Timing NULL_HANDLER = new NullTimingHandler();
private boolean timingsEnabled = true;
private boolean verboseEnabled = true;
private int historyInterval = -1;
private int historyLength = -1;
public void init() {
final TimingsConfiguration config = Configuration.getTimingsConfig();
setVerboseTimingsEnabled(config.isVerbose());
setTimingsEnabled(config.isEnabled());
setHistoryInterval(config.getHistoryInterval());
setHistoryLength(config.getHistoryLength());
Canary.log.debug("Neptune Timings: " + this.timingsEnabled +
" - Verbose: " + this.verboseEnabled +
" - Interval: " + timeSummary(this.historyInterval / 20) +
" - Length: " + timeSummary(this.historyLength / 20));
}
private static String timeSummary(int seconds) {
String time = "";
if (seconds > 60 * 60) {
time += TimeUnit.SECONDS.toHours(seconds) + "h";
seconds /= 60;
}
if (seconds > 0) {
time += TimeUnit.SECONDS.toMinutes(seconds) + "m";
}
return time;
}
@Override
public Timing of(Plugin plugin, String name, Timing groupHandler) {
return TimingsManager.getHandler(plugin.getName().toLowerCase(), name, groupHandler, true);
}
@Override
public Timing of(TaskOwner owner, ServerTask task) {
if (owner instanceof Plugin) {
return of((Plugin) owner, task.getClass().getName(), null);
} else {
return TimingsManager.getHandler(owner.getClass().getName(), task.getClass().getName(), null, true);
}
}
@Override
public boolean isTimingsEnabled() {
return this.timingsEnabled;
}
@Override
public void setTimingsEnabled(boolean enabled) {
this.timingsEnabled = enabled;
reset();
}
@Override
public boolean isVerboseTimingsEnabled() {
return this.verboseEnabled;
}
@Override
public void setVerboseTimingsEnabled(boolean enabled) {
this.verboseEnabled = enabled;
TimingsManager.needsRecheckEnabled = true;
}
@Override
public int getHistoryInterval() {
return this.historyInterval;
}
@Override
public void setHistoryInterval(int interval) {
this.historyInterval = Math.max(20 * 60, interval);
// Recheck the history length with the new Interval
if (this.historyLength != -1) {
setHistoryLength(this.historyLength);
}
}
@Override
public int getHistoryLength() {
return this.historyLength;
}
@Override
public void setHistoryLength(int length) {
// Cap at 12 History Frames, 1 hour at 5 minute frames.
int maxLength = this.historyInterval * this.MAX_HISTORY_FRAMES;
// For special cases of servers with special permission to bypass the
// max.
// This max helps keep data file sizes reasonable for processing on
// Aikar's Timing parser side.
// Setting this will not help you bypass the max unless Aikar has added
// an exception on the API side.
if (System.getProperty("timings.bypassMax") != null) {
maxLength = Integer.MAX_VALUE;
}
this.historyLength = Math.max(Math.min(maxLength, length), this.historyInterval);
Queue<TimingHistory> oldQueue = TimingsManager.HISTORY;
int frames = (getHistoryLength() / getHistoryInterval());
if (length > maxLength) {
Canary.log.warn(
"Timings Length too high. Requested " + length + ", max is " + maxLength
+ ". To get longer history, you must increase your interval. Set Interval to "
+ Math.ceil(length / this.MAX_HISTORY_FRAMES)
+ " to achieve this length.");
}
TimingsManager.HISTORY = EvictingQueue.create(frames);
TimingsManager.HISTORY.addAll(oldQueue);
}
@Override
public void reset() {
TimingsManager.reset();
}
@Override
public void generateReport(MessageReceiver sender) {
if (sender == null) {
sender = Canary.getServer();
}
TimingsExport.reportTimings(sender);
}
public static long getCost() {
return TimingsExport.getCost();
}
public static TimingHandler ofSafe(String name) {
return ofSafe(null, name, null);
}
public static Timing ofSafe(Plugin plugin, String name) {
return ofSafe(plugin != null ? plugin.getName() : "Minecraft - Invalid Plugin", name);
}
public static TimingHandler ofSafe(String name, Timing groupHandler) {
return ofSafe(null, name, groupHandler);
}
public static TimingHandler ofSafe(String groupName, String name) {
return TimingsManager.getHandler(groupName, name, null, false);
}
public static TimingHandler ofSafe(String groupName, String name, Timing groupHandler) {
return TimingsManager.getHandler(groupName, name, groupHandler, false);
}
}