Browse Source

Pull request #9840: REPORT-78589 && REPORT-78594 && REPORT-78596

Merge in DESIGN/design from ~JOHN.YING/design:feature/x to feature/x

* commit '3d17ac1cdafd08d8f42acdd4dbccbc41bfb0436b':
  REPORT-78589&&REPORT-78594&&REPORT-78596 改了一下注释以及创建线程池的工具类
  REPORT-78589&&REPORT-78594&&REPORT-78596 改了一下注释以及创建线程池的工具类
  REPORT-78589 使用不会触发检测的类,会有easy_check_log只记录的情况 REPORT-78594 交互问题 REPORT-78596 通用设置每次重启就恢复成默认状态了
feature/x
John.Ying 2 years ago
parent
commit
b33641f6ff
  1. 14
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 41
      designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java
  3. 8
      designer-base/src/main/java/com/fr/design/carton/FeedbackToolboxDialog.java
  4. 85
      designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java

14
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -6,6 +6,7 @@ package com.fr.design;
import com.fr.base.BaseXMLUtils; import com.fr.base.BaseXMLUtils;
import com.fr.base.Utils; import com.fr.base.Utils;
import com.fr.design.actions.help.alphafine.AlphaFineConfigManager; import com.fr.design.actions.help.alphafine.AlphaFineConfigManager;
import com.fr.design.carton.SwitchForSwingChecker;
import com.fr.design.constants.UIConstants; import com.fr.design.constants.UIConstants;
import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.DesignTableDataManager;
import com.fr.design.dialog.ErrorDialog; import com.fr.design.dialog.ErrorDialog;
@ -193,6 +194,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private DesignerStartupConfig designerStartupConfig = DesignerStartupConfig.getInstance(); private DesignerStartupConfig designerStartupConfig = DesignerStartupConfig.getInstance();
private SwitchForSwingChecker switchForSwingChecker = SwitchForSwingChecker.getInstance();
public static final String CAS_CERTIFICATE_PATH = "certificatePath"; public static final String CAS_CERTIFICATE_PATH = "certificatePath";
public static final String CAS_CERTIFICATE_PASSWORD = "certificatePass"; public static final String CAS_CERTIFICATE_PASSWORD = "certificatePass";
@ -1872,6 +1875,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readDesignerLoginAttr(reader); readDesignerLoginAttr(reader);
} else if (name.equals(fvsDesignerConfig.getName())) { } else if (name.equals(fvsDesignerConfig.getName())) {
readFvsDesignerConfig(reader); readFvsDesignerConfig(reader);
} else if (name.equals(SwitchForSwingChecker.XML_TAG)) {
readSwitchForSwingCheckerAttr(reader);
} else { } else {
readLayout(reader, name); readLayout(reader, name);
} }
@ -2091,6 +2096,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
reader.readXMLObject(DesignerPort.getInstance()); reader.readXMLObject(DesignerPort.getInstance());
} }
private void readSwitchForSwingCheckerAttr(XMLableReader reader) {
reader.readXMLObject(switchForSwingChecker);
}
/** /**
* Write XML.<br> * Write XML.<br>
* The method will be invoked when save data to XML file.<br> * The method will be invoked when save data to XML file.<br>
@ -2123,6 +2132,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writeComponentReuseNotificationInfo(writer); writeComponentReuseNotificationInfo(writer);
writeDesignerLoginAttr(writer); writeDesignerLoginAttr(writer);
writeFvsDesignerConfig(writer); writeFvsDesignerConfig(writer);
writeSwitchForSwingChecker(writer);
writer.end(); writer.end();
} }
@ -2437,6 +2447,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.fvsDesignerConfig.writeXML(writer); this.fvsDesignerConfig.writeXML(writer);
} }
private void writeSwitchForSwingChecker(XMLPrintWriter writer) {
this.switchForSwingChecker.writeXML(writer);
}
enum XmlHandler { enum XmlHandler {
Self; Self;

41
designer-base/src/main/java/com/fr/design/carton/EventDispatchThreadHangMonitor.java

@ -1,5 +1,6 @@
package com.fr.design.carton; package com.fr.design.carton;
import com.fr.concurrent.FineExecutors;
import com.fr.json.JSONObject; import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.ArrayUtils; import com.fr.stable.ArrayUtils;
@ -9,6 +10,7 @@ import com.fr.stable.StringUtils;
import com.fr.third.ibm.icu.text.SimpleDateFormat; import com.fr.third.ibm.icu.text.SimpleDateFormat;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.swing.SwingUtilities;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.AWTEvent; import java.awt.AWTEvent;
@ -23,6 +25,8 @@ import java.lang.management.ThreadMXBean;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/** /**
* 参考自git swinghelper * 参考自git swinghelper
@ -46,12 +50,10 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
* 开启间隔检测后两次检测的相隔时间ms * 开启间隔检测后两次检测的相隔时间ms
*/ */
private static final long CHECK_INTERVAL_MS = 100; private static final long CHECK_INTERVAL_MS = 100;
/** /**
* 最大的事件允许执行时间超过该时间则打印堆栈等相关信息 * 最大的事件允许执行时间超过该时间则打印堆栈等相关信息
*/ */
private static final long UNREASONABLE_DISPATCH_DURATION_MS = 1500; private static final long UNREASONABLE_DISPATCH_DURATION_MS = 1500;
/** /**
* 事件唯一编码用于方便日志的查看 * 事件唯一编码用于方便日志的查看
*/ */
@ -60,21 +62,19 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
* 输出日志所在地址 * 输出日志所在地址
*/ */
private static final String JOURNAL_FILE_PATH = StableUtils.pathJoin(ProductConstantsBase.getEnvHome(), "journal_log"); private static final String JOURNAL_FILE_PATH = StableUtils.pathJoin(ProductConstantsBase.getEnvHome(), "journal_log");
/** /**
* 类似于一个开关当该值为默认的false启动时定时任务在窗口开启前都不会对执行的事件进行检查 * 类似于一个开关当该值为默认的false启动时定时任务在窗口开启前都不会对执行的事件进行检查
*/ */
private boolean haveShownSomeComponent = false; private boolean haveShownSomeComponent = false;
/** /**
* 该链表为主要的实现定时任务的容器在重写的dispatchEvent中由pre方法将DispatchInfo加入到链表由post方法remove * 该链表为主要的实现定时任务的容器在重写的dispatchEvent中由pre方法将DispatchInfo加入到链表由post方法remove
*/ */
private final LinkedList<DispatchInfo> dispatches = new LinkedList<DispatchInfo>(); private final LinkedList<DispatchInfo> dispatches = new LinkedList<DispatchInfo>();
/** /**
* 一个变量用于控制easy监测模式的开关 * 一个变量用于控制easy监测模式的开关
*/ */
private boolean easyWitch = false; private boolean easyWitch = false;
private static ScheduledExecutorService scheduledExecutorService;
public boolean isEasyWitch() { public boolean isEasyWitch() {
return easyWitch; return easyWitch;
@ -194,12 +194,12 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
} }
//事件处理完后的时间判断 //事件处理完后的时间判断
public void dispose() { public void dispose() {
if (totalTime() > UNREASONABLE_DISPATCH_DURATION_MS) { if (timeSoFar() > UNREASONABLE_DISPATCH_DURATION_MS) {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), simpleDateFormat.format(System.currentTimeMillis())); jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Output_Time"), simpleDateFormat.format(System.currentTimeMillis()));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "eventQueue_" + hangNumber); jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Event_Number"), "eventQueue_" + hangNumber);
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Start_Time"), simpleDateFormat.format(startDispatchTimeMillis)); jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Start_Time"), simpleDateFormat.format(startDispatchTimeMillis));
jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), totalTime() + "ms"); jsonObject.put(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Carton_Task_Total_Time"), timeSoFar() + "ms");
outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG); outPutJournalLog(jsonObject.toString(), SwitchForSwingChecker.EASY_CHECK_FLAG);
} }
} }
@ -234,6 +234,32 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
} }
/**
* 参考SwingExplorer,在处理模态框时没有做特殊处理也不会输出卡顿堆栈
* 原因是SwingExplorer窗口一直有一个监听事件不断的addremove
* 由于卡顿日志输出的是事件连续执行的时间所以一个长时间存在的模态框被不断重复的监听事件刷新时间就不会输出了
* 当检测开关打开后在这里模拟一下监听事件给个不耗时的任务就可以
*/
public void startFilterModalWindow() {
scheduledExecutorService = FineExecutors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//不用干事,切个片就可以
}
});
}
}, 0, 500, TimeUnit.MILLISECONDS);
}
public void stopFilterModalWindow() {
if (scheduledExecutorService != null) {
scheduledExecutorService.shutdown();
}
}
/** /**
* Sets up a timer to check for hangs frequently. * Sets up a timer to check for hangs frequently.
* 初始化一个Timer * 初始化一个Timer
@ -363,4 +389,5 @@ public final class EventDispatchThreadHangMonitor extends EventQueue {
} }
return result.toString(); return result.toString();
} }
} }

8
designer-base/src/main/java/com/fr/design/carton/FeedbackToolboxDialog.java

@ -280,7 +280,13 @@ public class FeedbackToolboxDialog extends JDialog {
} else { } else {
SwitchForSwingChecker.stopTimerChecker(); SwitchForSwingChecker.stopTimerChecker();
} }
FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Basic_Common_Save_Successfully")); createBodyPanel();
remove(generalSettingPanel);
add(body);
setPreferredSize(body.getPreferredSize());
setSwitches(!StringUtils.isEmpty(GeneralUtils.objectToString(uiDatePicker.getSelectedItem())));
repaint();
setVisible(true);
}); });
actionsPanel.add(confirmButton, BorderLayout.WEST); actionsPanel.add(confirmButton, BorderLayout.WEST);

85
designer-base/src/main/java/com/fr/design/carton/SwitchForSwingChecker.java

@ -10,13 +10,17 @@ import com.fr.log.FineLoggerFactory;
import com.fr.stable.ProductConstantsBase; import com.fr.stable.ProductConstantsBase;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLReadable;
import com.fr.stable.xml.XMLWriter;
import com.fr.stable.xml.XMLableReader;
import sun.awt.AppContext; import sun.awt.AppContext;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import java.io.IOException;
import java.io.File; import java.io.File;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,13 +29,21 @@ import java.util.Map;
import java.util.Date; import java.util.Date;
import java.util.Calendar; import java.util.Calendar;
public class SwitchForSwingChecker { public class SwitchForSwingChecker implements XMLReadable, XMLWriter {
/** /**
* /定时任务的开关 * Designer4Debug类名
*/
private static final String DEBUG_MAIN_CLASS_NAME = "com.fr.start.Designer4Debug";
/**
* XML标签
*/
public static final String XML_TAG = "SwitchForSwingChecker";
/**
* 定时任务的开关
*/ */
private static boolean checkerTimerSwitch = false; private static boolean checkerTimerSwitch = false;
/** /**
* /简单记录事件执行时间的开关 * 简单记录事件执行时间的开关
*/ */
private static boolean easyChecker = false; private static boolean easyChecker = false;
/** /**
@ -41,7 +53,7 @@ public class SwitchForSwingChecker {
public static final int EASY_CHECK_FLAG = 1; public static final int EASY_CHECK_FLAG = 1;
/** /**
* /日志存储地址 * 日志存储地址
*/ */
public static final String JOURNAL_FILE_PATH = StableUtils.pathJoin(ProductConstantsBase.getEnvHome(), "journal_log"); public static final String JOURNAL_FILE_PATH = StableUtils.pathJoin(ProductConstantsBase.getEnvHome(), "journal_log");
public static final String EASY_CHECKER_FILE_NAME = "easy_check_log.csv"; public static final String EASY_CHECKER_FILE_NAME = "easy_check_log.csv";
@ -54,12 +66,21 @@ public class SwitchForSwingChecker {
return easyChecker; return easyChecker;
} }
public static volatile SwitchForSwingChecker switchForSwingChecker = new SwitchForSwingChecker();
public static SwitchForSwingChecker getInstance() {
return switchForSwingChecker;
}
public static void startTimerChecker() { public static void startTimerChecker() {
if (!checkerTimerSwitch) { if (!checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.initTimer(); EventDispatchThreadHangMonitor.INSTANCE.initTimer();
CartonThreadExecutorPool.getTimerThreadExecutorPool().initTimer(); CartonThreadExecutorPool.getTimerThreadExecutorPool().initTimer();
EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(true); EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(true);
checkerTimerSwitch = true; checkerTimerSwitch = true;
if (!easyChecker) {
EventDispatchThreadHangMonitor.INSTANCE.startFilterModalWindow();
}
} }
} }
@ -69,6 +90,9 @@ public class SwitchForSwingChecker {
CartonThreadExecutorPool.getTimerThreadExecutorPool().stopTimer(); CartonThreadExecutorPool.getTimerThreadExecutorPool().stopTimer();
EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(false); EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(false);
checkerTimerSwitch = false; checkerTimerSwitch = false;
if (!easyChecker) {
EventDispatchThreadHangMonitor.INSTANCE.stopFilterModalWindow();
}
} }
} }
@ -77,6 +101,9 @@ public class SwitchForSwingChecker {
EventDispatchThreadHangMonitor.INSTANCE.setEasyWitch(true); EventDispatchThreadHangMonitor.INSTANCE.setEasyWitch(true);
CartonThreadExecutorPool.getTimerThreadExecutorPool().setEasyWitch(true); CartonThreadExecutorPool.getTimerThreadExecutorPool().setEasyWitch(true);
easyChecker = true; easyChecker = true;
if (!checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.startFilterModalWindow();
}
} }
} }
@ -85,6 +112,9 @@ public class SwitchForSwingChecker {
EventDispatchThreadHangMonitor.INSTANCE.setEasyWitch(false); EventDispatchThreadHangMonitor.INSTANCE.setEasyWitch(false);
CartonThreadExecutorPool.getTimerThreadExecutorPool().setEasyWitch(false); CartonThreadExecutorPool.getTimerThreadExecutorPool().setEasyWitch(false);
easyChecker = false; easyChecker = false;
if (!checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.stopFilterModalWindow();
}
} }
} }
@ -215,10 +245,15 @@ public class SwitchForSwingChecker {
/** /**
* 初始化监控任务主要是替换EventQueue以及SwingWorker执行任务的线程池 * 初始化监控任务主要是替换EventQueue以及SwingWorker执行任务的线程池
*
*/ */
public static void initThreadMonitoring () { public static void initThreadMonitoring () {
EventDispatchThreadHangMonitor.initMonitoring(); String mainClass = System.getProperty("sun.java.command");
AppContext.getAppContext().put(SwingWorker.class, CartonThreadExecutorPool.getTimerThreadExecutorPool()); //判断一下,如果是以Designer4Debug启动,就不注册代码,不然会覆盖掉SwingExplorer,导致其无法使用
if (!StringUtils.equals(mainClass, DEBUG_MAIN_CLASS_NAME)) {
EventDispatchThreadHangMonitor.initMonitoring();
AppContext.getAppContext().put(SwingWorker.class, CartonThreadExecutorPool.getTimerThreadExecutorPool());
}
} }
/** /**
@ -237,4 +272,40 @@ public class SwitchForSwingChecker {
public static boolean isCartonExists() { public static boolean isCartonExists() {
return isCartonExists(new Date()); return isCartonExists(new Date());
} }
private void initSwitchChecker() {
if (easyChecker) {
EventDispatchThreadHangMonitor.INSTANCE.setEasyWitch(true);
CartonThreadExecutorPool.getTimerThreadExecutorPool().setEasyWitch(true);
}
if (checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.initTimer();
CartonThreadExecutorPool.getTimerThreadExecutorPool().initTimer();
EventDispatchThreadHangMonitor.INSTANCE.setTimerWitch(true);
}
if (easyChecker || checkerTimerSwitch) {
EventDispatchThreadHangMonitor.INSTANCE.startFilterModalWindow();
}
}
@Override
public void readXML(XMLableReader reader) {
if (reader.isAttr()) {
checkerTimerSwitch = reader.getAttrAsBoolean("checkerTimerSwitch", false);
easyChecker = reader.getAttrAsBoolean("easyChecker", false);
}
try {
initSwitchChecker();
} catch (Throwable t) {
FineLoggerFactory.getLogger().error("read checker attr fail", t);
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
writer.startTAG(XML_TAG);
writer.attr("checkerTimerSwitch", checkerTimerSwitch);
writer.attr("easyChecker", easyChecker);
writer.end();
}
} }

Loading…
Cancel
Save