ThreadPool manager rework.
This commit is contained in:
@@ -309,7 +309,6 @@ import handlers.telnethandlers.server.ServerAbort;
|
||||
import handlers.telnethandlers.server.ServerRestart;
|
||||
import handlers.telnethandlers.server.ServerShutdown;
|
||||
import handlers.telnethandlers.server.Status;
|
||||
import handlers.telnethandlers.server.ThreadPoolDebug;
|
||||
import handlers.usercommandhandlers.ChannelDelete;
|
||||
import handlers.usercommandhandlers.ChannelInfo;
|
||||
import handlers.usercommandhandlers.ChannelLeave;
|
||||
@@ -751,7 +750,6 @@ public class MasterHandler
|
||||
TelnetServer.getInstance().addHandler(new ServerRestart());
|
||||
TelnetServer.getInstance().addHandler(new ServerShutdown());
|
||||
TelnetServer.getInstance().addHandler(new Status());
|
||||
TelnetServer.getInstance().addHandler(new ThreadPoolDebug());
|
||||
TelnetServer.getInstance().addHandler(new handlers.telnethandlers.server.Debug());
|
||||
}
|
||||
|
||||
|
@@ -20,14 +20,12 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.GameServer;
|
||||
import com.l2jmobius.gameserver.GameTimeController;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
|
||||
import com.l2jmobius.gameserver.handler.IAdminCommandHandler;
|
||||
@@ -72,14 +70,6 @@ public class AdminServerInfo implements IAdminCommandHandler
|
||||
html.replace("%usedMem%", (RunTime.maxMemory() / mb) - (((RunTime.maxMemory() - RunTime.totalMemory()) + RunTime.freeMemory()) / mb));
|
||||
html.replace("%freeMem%", ((RunTime.maxMemory() - RunTime.totalMemory()) + RunTime.freeMemory()) / mb);
|
||||
html.replace("%totalMem%", Runtime.getRuntime().maxMemory() / 1048576);
|
||||
html.replace("%theardInfoGen%", buildTheardInfo("GENERAL"));
|
||||
html.replace("%theardInfoEff%", buildTheardInfo("EFFECTS"));
|
||||
html.replace("%theardInfoAi%", buildTheardInfo("AI"));
|
||||
html.replace("%theardInfoEvent%", buildTheardInfo("EVENT"));
|
||||
html.replace("%theardInfoPack%", buildTheardInfo("PACKETS"));
|
||||
html.replace("%theardInfoIOPack%", buildTheardInfo("IOPACKETS"));
|
||||
html.replace("%theardInfoGenTask%", buildTheardInfo("GENERAL_TASKS"));
|
||||
html.replace("%theardInfoEvnTask%", buildTheardInfo("EVENT_TASKS"));
|
||||
activeChar.sendPacket(html);
|
||||
}
|
||||
return true;
|
||||
@@ -96,22 +86,6 @@ public class AdminServerInfo implements IAdminCommandHandler
|
||||
return days + " Days, " + hours + " Hours, " + TimeUnit.MILLISECONDS.toMinutes(time) + " Minutes";
|
||||
}
|
||||
|
||||
private String buildTheardInfo(String category)
|
||||
{
|
||||
final StringBuilder tb = new StringBuilder();
|
||||
|
||||
tb.append("<table width=\"270\" border=\"0\" bgcolor=\"444444\">");
|
||||
for (Entry<String, Object> info : ThreadPoolManager.getInstance().getStats(category).getSet().entrySet())
|
||||
{
|
||||
tb.append("<tr>");
|
||||
tb.append("<td>" + info.getKey() + ":</td>");
|
||||
tb.append("<td><font color=\"00FF00\">" + info.getValue() + "</font></td>");
|
||||
tb.append("</tr>");
|
||||
}
|
||||
tb.append("</table>");
|
||||
return tb.toString();
|
||||
}
|
||||
|
||||
private int getPlayersCount(String type)
|
||||
{
|
||||
switch (type)
|
||||
|
@@ -46,7 +46,7 @@ public class AdminTest implements IAdminCommandHandler
|
||||
{
|
||||
if (command.equals("admin_stats"))
|
||||
{
|
||||
for (String line : ThreadPoolManager.getInstance().getStats())
|
||||
for (String line : ThreadPoolManager.getStats())
|
||||
{
|
||||
activeChar.sendMessage(line);
|
||||
}
|
||||
|
@@ -57,7 +57,7 @@ public class ClassChange extends AbstractEffect
|
||||
{
|
||||
final L2PcInstance player = effected.getActingPlayer();
|
||||
// TODO: FIX ME - Executing 1 second later otherwise interupted exception during storeCharBase()
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(() ->
|
||||
ThreadPoolManager.schedule(() ->
|
||||
{
|
||||
final int activeClass = player.getClassId().getId();
|
||||
|
||||
|
@@ -67,7 +67,7 @@ public final class ServitorShare extends AbstractEffect
|
||||
|
||||
if (effected != null)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleEffect(new ScheduledEffectExitTask(effected, info.getSkill().getId()), 100);
|
||||
ThreadPoolManager.schedule(new ScheduledEffectExitTask(effected, info.getSkill().getId()), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -162,7 +162,7 @@ public class JailHandler implements IPunishmentHandler
|
||||
OlympiadManager.getInstance().removeDisconnectedCompetitor(player);
|
||||
}
|
||||
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new TeleportTask(player, L2JailZone.getLocationIn()), 2000);
|
||||
ThreadPoolManager.schedule(new TeleportTask(player, L2JailZone.getLocationIn()), 2000);
|
||||
|
||||
// Open a Html message to inform the player
|
||||
final NpcHtmlMessage msg = new NpcHtmlMessage();
|
||||
@@ -198,7 +198,7 @@ public class JailHandler implements IPunishmentHandler
|
||||
*/
|
||||
private static void removeFromPlayer(L2PcInstance player)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new TeleportTask(player, L2JailZone.getLocationOut()), 2000);
|
||||
ThreadPoolManager.schedule(new TeleportTask(player, L2JailZone.getLocationOut()), 2000);
|
||||
|
||||
// Open a Html message to inform the player
|
||||
final NpcHtmlMessage msg = new NpcHtmlMessage();
|
||||
|
@@ -68,7 +68,7 @@ public class Debug implements ITelnetCommand
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "Debug <decay/packetsend/PacketTP/IOPacketTP/GeneralTP/full>";
|
||||
return "Debug <decay/packetsend/full>";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,90 +108,6 @@ public class Debug implements ITelnetCommand
|
||||
player.sendPacket(sp);
|
||||
return "Packet has been sent!";
|
||||
}
|
||||
case "PacketTP":
|
||||
{
|
||||
final String str = ThreadPoolManager.getInstance().getPacketStats();
|
||||
int i = 0;
|
||||
File f = new File("./log/StackTrace-PacketTP-" + i + ".txt");
|
||||
while (f.exists())
|
||||
{
|
||||
i++;
|
||||
f = new File("./log/StackTrace-PacketTP-" + i + ".txt");
|
||||
}
|
||||
f.getParentFile().mkdirs();
|
||||
try
|
||||
{
|
||||
Files.write(f.toPath(), str.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Couldn't write packet tp.", e);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case "IOPacketTP":
|
||||
{
|
||||
final String str = ThreadPoolManager.getInstance().getIOPacketStats();
|
||||
int i = 0;
|
||||
File f = new File("./log/StackTrace-IOPacketTP-" + i + ".txt");
|
||||
while (f.exists())
|
||||
{
|
||||
i++;
|
||||
f = new File("./log/StackTrace-IOPacketTP-" + i + ".txt");
|
||||
}
|
||||
f.getParentFile().mkdirs();
|
||||
try
|
||||
{
|
||||
Files.write(f.toPath(), str.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Couldn't write packet tp.", e);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case "GeneralTP":
|
||||
{
|
||||
final String str = ThreadPoolManager.getInstance().getGeneralStats();
|
||||
int i = 0;
|
||||
File f = new File("./log/StackTrace-GeneralTP-" + i + ".txt");
|
||||
while (f.exists())
|
||||
{
|
||||
i++;
|
||||
f = new File("./log/StackTrace-GeneralTP-" + i + ".txt");
|
||||
}
|
||||
f.getParentFile().mkdirs();
|
||||
try
|
||||
{
|
||||
Files.write(f.toPath(), str.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Couldn't write packet tp.", e);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case "GeneralScheduledTP":
|
||||
{
|
||||
final String str = ThreadPoolManager.getInstance().getGeneralStats();
|
||||
int i = 0;
|
||||
File f = new File("./log/StackTrace-GeneralScheduledTP-" + i + ".txt");
|
||||
while (f.exists())
|
||||
{
|
||||
i++;
|
||||
f = new File("./log/StackTrace-GeneralScheduledTP-" + i + ".txt");
|
||||
}
|
||||
f.getParentFile().mkdirs();
|
||||
try
|
||||
{
|
||||
Files.write(f.toPath(), str.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Couldn't write packet tp.", e);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
case "full":
|
||||
{
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
@@ -283,7 +199,7 @@ public class Debug implements ITelnetCommand
|
||||
}
|
||||
|
||||
sb.append("\r\n## Thread Pool Manager Statistics ##\r\n");
|
||||
for (String line : ThreadPoolManager.getInstance().getStats())
|
||||
for (String line : ThreadPoolManager.getStats())
|
||||
{
|
||||
sb.append(line);
|
||||
sb.append("\r\n");
|
||||
|
@@ -42,9 +42,9 @@ public class Performance implements ITelnetCommand
|
||||
@Override
|
||||
public String handle(ChannelHandlerContext ctx, String[] args)
|
||||
{
|
||||
ThreadPoolManager.getInstance().purge();
|
||||
// ThreadPoolManager.purge();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (String line : ThreadPoolManager.getInstance().getStats())
|
||||
for (String line : ThreadPoolManager.getStats())
|
||||
{
|
||||
sb.append(line + Config.EOL);
|
||||
}
|
||||
|
@@ -42,9 +42,9 @@ public class Purge implements ITelnetCommand
|
||||
@Override
|
||||
public String handle(ChannelHandlerContext ctx, String[] args)
|
||||
{
|
||||
ThreadPoolManager.getInstance().purge();
|
||||
ThreadPoolManager.purge();
|
||||
final StringBuilder sb = new StringBuilder("STATUS OF THREAD POOLS AFTER PURGE COMMAND:" + Config.EOL);
|
||||
for (String line : ThreadPoolManager.getInstance().getStats())
|
||||
for (String line : ThreadPoolManager.getStats())
|
||||
{
|
||||
sb.append(line + Config.EOL);
|
||||
}
|
||||
|
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package handlers.telnethandlers.server;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager.RunnableWrapper;
|
||||
import com.l2jmobius.gameserver.network.telnet.ITelnetCommand;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class ThreadPoolDebug implements ITelnetCommand
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(ThreadPoolDebug.class.getName());
|
||||
|
||||
@Override
|
||||
public String getCommand()
|
||||
{
|
||||
return "threadpooldebug";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage()
|
||||
{
|
||||
return "threadpooldebug [effect, general, ai, events]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String handle(ChannelHandlerContext ctx, String[] args)
|
||||
{
|
||||
String pool = "_generalScheduledThreadPool";
|
||||
if (args.length > 0)
|
||||
{
|
||||
switch (args[0])
|
||||
{
|
||||
case "effect":
|
||||
{
|
||||
pool = "_effectsScheduledThreadPool";
|
||||
break;
|
||||
}
|
||||
case "general":
|
||||
{
|
||||
pool = "_generalScheduledThreadPool";
|
||||
break;
|
||||
}
|
||||
case "ai":
|
||||
{
|
||||
pool = "_aiScheduledThreadPool";
|
||||
break;
|
||||
}
|
||||
case "events":
|
||||
{
|
||||
pool = "_eventScheduledThreadPool";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return args[0] + " is not implemented!";
|
||||
}
|
||||
}
|
||||
}
|
||||
final ScheduledThreadPoolExecutor executor = getObject(ThreadPoolManager.class, ThreadPoolManager.getInstance(), pool, ScheduledThreadPoolExecutor.class);
|
||||
if (executor == null)
|
||||
{
|
||||
return "Couldn't retreive " + pool + "!";
|
||||
}
|
||||
|
||||
Class<?> adapterClass;
|
||||
try
|
||||
{
|
||||
adapterClass = Class.forName("java.util.concurrent.Executors$RunnableAdapter");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e.getMessage();
|
||||
}
|
||||
|
||||
final Map<String, Integer> tasks = new HashMap<>();
|
||||
for (Runnable run : executor.getQueue())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (run instanceof FutureTask)
|
||||
{
|
||||
final Object callableObject = getObject(FutureTask.class, run, "callable", Object.class);
|
||||
final Object taskObject = getObject(adapterClass, callableObject, "task", Object.class);
|
||||
|
||||
if (taskObject instanceof RunnableWrapper)
|
||||
{
|
||||
final Runnable task = getObject(RunnableWrapper.class, taskObject, "_r", Runnable.class);
|
||||
final String name = task.getClass().getName();
|
||||
final int times = tasks.containsKey(name) ? tasks.get(name) : 0;
|
||||
tasks.put(name, times + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(pool + " queue size: " + executor.getQueue().size() + Config.EOL);
|
||||
|
||||
tasks.entrySet().stream().sorted(Comparator.comparingInt(Entry::getValue)).forEach(entry -> sb.append("Class: " + entry.getKey() + " = " + entry.getValue() + Config.EOL));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static <T> T getObject(Class<?> sourceClass, Object sourceInstance, String fieldName, Class<T> targetClass)
|
||||
{
|
||||
try
|
||||
{
|
||||
final Field field = sourceClass.getDeclaredField(fieldName);
|
||||
|
||||
// Mark down if field was accessible
|
||||
final boolean isAccessible = field.isAccessible();
|
||||
|
||||
// Enforce accessible to retrieve the object associated with this field
|
||||
if (!isAccessible)
|
||||
{
|
||||
field.setAccessible(true);
|
||||
}
|
||||
|
||||
// Get the object
|
||||
final Object fieldObject = field.get(sourceInstance);
|
||||
|
||||
// Restore the original accessible state.
|
||||
field.setAccessible(isAccessible);
|
||||
|
||||
// Make sure the object is the one we expect to be
|
||||
if (targetClass.isInstance(fieldObject))
|
||||
{
|
||||
return targetClass.cast(fieldObject);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Error while retrieving object of " + sourceInstance.getClass().getName() + "." + fieldName, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user