mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 18:50:06 -08:00
refactor: removed client side threads from a server, improved test log files rotation;
This commit is contained in:
parent
0470ae9799
commit
c5632f6868
6 changed files with 75 additions and 62 deletions
|
|
@ -58,7 +58,7 @@ public class MageEditorPane extends JEditorPane {
|
||||||
if (Arrays.stream(getHyperlinkListeners()).findAny().isPresent()) {
|
if (Arrays.stream(getHyperlinkListeners()).findAny().isPresent()) {
|
||||||
throw new IllegalStateException("Wrong code usage: popup links support enabled already");
|
throw new IllegalStateException("Wrong code usage: popup links support enabled already");
|
||||||
}
|
}
|
||||||
addHyperlinkListener(e -> ThreadUtils.threadPoolPopups.submit(() -> {
|
addHyperlinkListener(e -> MageUI.threadPoolPopups.submit(() -> {
|
||||||
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300) == 0) {
|
if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_SHOW_TOOLTIPS_DELAY, 300) == 0) {
|
||||||
// if disabled
|
// if disabled
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,51 @@
|
||||||
package mage.client.components;
|
package mage.client.components;
|
||||||
|
|
||||||
|
import mage.utils.ThreadUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
|
|
||||||
public class MageUI {
|
public class MageUI {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(MageUI.class);
|
||||||
|
|
||||||
private final Map<MageComponents, Component> ui = new EnumMap<>(MageComponents.class);
|
private final Map<MageComponents, Component> ui = new EnumMap<>(MageComponents.class);
|
||||||
private final Map<MageComponents, Object> sync = new EnumMap<>(MageComponents.class);
|
private final Map<MageComponents, Object> sync = new EnumMap<>(MageComponents.class);
|
||||||
|
|
||||||
|
public static final ThreadPoolExecutor threadPoolPopups;
|
||||||
|
private static int threadCount;
|
||||||
|
|
||||||
|
static {
|
||||||
|
threadPoolPopups = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new ThreadFactory() {
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable runnable) {
|
||||||
|
threadCount++;
|
||||||
|
Thread thread = new Thread(runnable, "POPUP-" + threadCount);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
@Override
|
||||||
|
protected void afterExecute(Runnable r, Throwable t) {
|
||||||
|
super.afterExecute(r, t);
|
||||||
|
|
||||||
|
// catch errors in popup threads (example: card popup over cards or chat/log messages)
|
||||||
|
t = ThreadUtils.findRealException(r, t);
|
||||||
|
if (t != null) {
|
||||||
|
logger.error("Catch unhandled error in POPUP thread: " + t.getMessage(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
threadPoolPopups.prestartAllCoreThreads();
|
||||||
|
}
|
||||||
|
|
||||||
public JButton getButton(MageComponents name) throws InterruptedException {
|
public JButton getButton(MageComponents name) throws InterruptedException {
|
||||||
//System.out.println("request for " + name);
|
//System.out.println("request for " + name);
|
||||||
Object buttonSync;
|
Object buttonSync;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import mage.client.SessionHandler;
|
||||||
import mage.client.cards.BigCard;
|
import mage.client.cards.BigCard;
|
||||||
import mage.client.cards.CardEventProducer;
|
import mage.client.cards.CardEventProducer;
|
||||||
import mage.client.components.MageComponents;
|
import mage.client.components.MageComponents;
|
||||||
|
import mage.client.components.MageUI;
|
||||||
import mage.client.dialog.PreferencesDialog;
|
import mage.client.dialog.PreferencesDialog;
|
||||||
import mage.client.game.GamePane;
|
import mage.client.game.GamePane;
|
||||||
import mage.client.plugins.impl.Plugins;
|
import mage.client.plugins.impl.Plugins;
|
||||||
|
|
@ -187,7 +188,7 @@ public class MageActionCallback implements ActionCallback {
|
||||||
private void showCardHintPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
|
private void showCardHintPopup(final TransferData data, final Component parentComponent, final Point parentPoint) {
|
||||||
MageCard cardPanel = data.getComponent().getTopPanelRef();
|
MageCard cardPanel = data.getComponent().getTopPanelRef();
|
||||||
|
|
||||||
ThreadUtils.threadPoolPopups.submit(new Runnable() {
|
MageUI.threadPoolPopups.submit(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ThreadUtils.sleep(tooltipDelay);
|
ThreadUtils.sleep(tooltipDelay);
|
||||||
|
|
@ -647,7 +648,7 @@ public class MageActionCallback implements ActionCallback {
|
||||||
private void displayEnlargedCard(final CardView cardView, final TransferData data) {
|
private void displayEnlargedCard(final CardView cardView, final TransferData data) {
|
||||||
MageCard cardPanel = data.getComponent().getTopPanelRef();
|
MageCard cardPanel = data.getComponent().getTopPanelRef();
|
||||||
|
|
||||||
ThreadUtils.threadPoolPopups.submit(() -> {
|
MageUI.threadPoolPopups.submit(() -> {
|
||||||
if (cardView == null) {
|
if (cardView == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@ import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.sound.sampled.AudioFormat;
|
import javax.sound.sampled.AudioFormat;
|
||||||
import javax.sound.sampled.AudioSystem;
|
import javax.sound.sampled.AudioSystem;
|
||||||
|
|
@ -25,6 +29,31 @@ public class LinePool {
|
||||||
private final org.apache.log4j.Logger logger = Logger.getLogger(LinePool.class);
|
private final org.apache.log4j.Logger logger = Logger.getLogger(LinePool.class);
|
||||||
private static final int LINE_CLEANUP_INTERVAL = 30000;
|
private static final int LINE_CLEANUP_INTERVAL = 30000;
|
||||||
|
|
||||||
|
private static final ThreadPoolExecutor threadPoolSounds;
|
||||||
|
private static int threadCount = 0;
|
||||||
|
static {
|
||||||
|
threadPoolSounds = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new ThreadFactory() {
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable runnable) {
|
||||||
|
threadCount++;
|
||||||
|
Thread thread = new Thread(runnable, "SOUND-" + threadCount);
|
||||||
|
thread.setDaemon(true);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
@Override
|
||||||
|
protected void afterExecute(Runnable r, Throwable t) {
|
||||||
|
super.afterExecute(r, t);
|
||||||
|
t = ThreadUtils.findRealException(r, t);
|
||||||
|
if (t != null) {
|
||||||
|
// TODO: show sound errors in client logs?
|
||||||
|
//logger.error("Catch unhandled error in SOUND thread: " + t.getMessage(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
threadPoolSounds.prestartAllCoreThreads();
|
||||||
|
}
|
||||||
|
|
||||||
private final Queue<SourceDataLine> freeLines = new ArrayDeque<>();
|
private final Queue<SourceDataLine> freeLines = new ArrayDeque<>();
|
||||||
private final Queue<SourceDataLine> activeLines = new ArrayDeque<>();
|
private final Queue<SourceDataLine> activeLines = new ArrayDeque<>();
|
||||||
private final Set<SourceDataLine> busyLines = new HashSet<>();
|
private final Set<SourceDataLine> busyLines = new HashSet<>();
|
||||||
|
|
@ -106,7 +135,7 @@ public class LinePool {
|
||||||
}
|
}
|
||||||
logLineStats();
|
logLineStats();
|
||||||
}
|
}
|
||||||
ThreadUtils.threadPoolSounds.submit(() -> {
|
threadPoolSounds.submit(() -> {
|
||||||
synchronized (LinePool.this) {
|
synchronized (LinePool.this) {
|
||||||
try {
|
try {
|
||||||
if (!line.isOpen()) {
|
if (!line.isOpen()) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package mage.utils;
|
package mage.utils;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import java.util.concurrent.CancellationException;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Util method to work with threads.
|
* Util method to work with threads.
|
||||||
|
|
@ -11,57 +11,6 @@ import java.util.concurrent.*;
|
||||||
*/
|
*/
|
||||||
public final class ThreadUtils {
|
public final class ThreadUtils {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ThreadUtils.class);
|
|
||||||
|
|
||||||
public static final ThreadPoolExecutor threadPoolSounds;
|
|
||||||
public static final ThreadPoolExecutor threadPoolPopups;
|
|
||||||
private static int threadCount;
|
|
||||||
|
|
||||||
static {
|
|
||||||
threadPoolSounds = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new ThreadFactory() {
|
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable runnable) {
|
|
||||||
threadCount++;
|
|
||||||
Thread thread = new Thread(runnable, "SOUND-" + threadCount);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
@Override
|
|
||||||
protected void afterExecute(Runnable r, Throwable t) {
|
|
||||||
super.afterExecute(r, t);
|
|
||||||
t = findRealException(r, t);
|
|
||||||
if (t != null) {
|
|
||||||
// TODO: show sound errors in client logs?
|
|
||||||
//logger.error("Catch unhandled error in SOUND thread: " + t.getMessage(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
threadPoolSounds.prestartAllCoreThreads();
|
|
||||||
|
|
||||||
threadPoolPopups = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), new ThreadFactory() {
|
|
||||||
@Override
|
|
||||||
public Thread newThread(Runnable runnable) {
|
|
||||||
threadCount++;
|
|
||||||
Thread thread = new Thread(runnable, "POPUP-" + threadCount);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
return thread;
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
@Override
|
|
||||||
protected void afterExecute(Runnable r, Throwable t) {
|
|
||||||
super.afterExecute(r, t);
|
|
||||||
|
|
||||||
// catch errors in popup threads (example: card popup over cards or chat/log messages)
|
|
||||||
t = findRealException(r, t);
|
|
||||||
if (t != null) {
|
|
||||||
logger.error("Catch unhandled error in POPUP thread: " + t.getMessage(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
threadPoolPopups.prestartAllCoreThreads();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void sleep(int millis) {
|
public static void sleep(int millis) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(millis);
|
Thread.sleep(millis);
|
||||||
|
|
@ -81,9 +30,6 @@ public final class ThreadUtils {
|
||||||
/**
|
/**
|
||||||
* Find real exception object after thread task completed. Can be used in afterExecute
|
* Find real exception object after thread task completed. Can be used in afterExecute
|
||||||
*
|
*
|
||||||
* @param r
|
|
||||||
* @param t
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public static Throwable findRealException(Runnable r, Throwable t) {
|
public static Throwable findRealException(Runnable r, Throwable t) {
|
||||||
// executer.submit - return exception in result
|
// executer.submit - return exception in result
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,10 @@ log4j.appender.logfileByIndex.MaxBackupIndex=3
|
||||||
log4j.appender.logfileByIndex.append=true
|
log4j.appender.logfileByIndex.append=true
|
||||||
|
|
||||||
#file log - errors only
|
#file log - errors only
|
||||||
log4j.appender.watchdog=org.apache.log4j.FileAppender
|
log4j.appender.watchdog=org.apache.log4j.RollingFileAppender
|
||||||
log4j.appender.watchdog.layout=org.apache.log4j.PatternLayout
|
log4j.appender.watchdog.layout=org.apache.log4j.PatternLayout
|
||||||
log4j.appender.watchdog.layout.ConversionPattern=%-5p [%d{yyyy-MM-dd HH:mm [ss:SSS]}] %C{1}[%t]: %m%n
|
log4j.appender.watchdog.layout.ConversionPattern=%-5p [%d{yyyy-MM-dd HH:mm [ss:SSS]}] %C{1}[%t]: %m%n
|
||||||
log4j.appender.watchdog.file=magetestErrors.log
|
log4j.appender.watchdog.file=magetestErrors.log
|
||||||
|
log4j.appender.watchdog.MaxFileSize=10MB
|
||||||
|
log4j.appender.watchdog.MaxBackupIndex=1
|
||||||
log4j.appender.watchdog.Threshold=error
|
log4j.appender.watchdog.Threshold=error
|
||||||
Loading…
Add table
Add a link
Reference in a new issue