<commit_before>package net.sf.jailer.ui.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

import net.sf.jailer.database.Session;
import net.sf.jailer.ui.UIUtil;

public class AWTWatchdog {

	private static final long MAX_DELAY = 10000;

	public static void start() {
		try {
			Thread watchdog = new Thread(new Runnable() {
				@Override
				public void run() {
					boolean issueSent = false;
					for (;;) {
						try {
							long t = System.currentTimeMillis();
							Thread.sleep(1000);
							if (t + 5000 < System.currentTimeMillis()) {
								setStarttime(0);
								continue;
							}
						} catch (InterruptedException e) {
							// ignore
						}
						
						long st = getStarttime();
						if (st != 0 && st + MAX_DELAY < System.currentTimeMillis()) {
							if (!issueSent) {
								String dump;
								try {
									dump = sendThreadDump();
								} catch (Throwable t) {
									StringWriter sw = new StringWriter();
							        PrintWriter pw = new PrintWriter(sw);
							        t.printStackTrace(pw);
							        dump = sw.toString();
								}
								dump = "AWT-Thread hanging: " + dump;
								Session._log.error(dump);
								final int MAX_CL = 1000;
					            String iMsg = dump;
					            if (iMsg.length() > MAX_CL) {
					            	iMsg = iMsg.substring(0, MAX_CL);
					            }
								UIUtil.sendIssue("AWTHanging", iMsg);
								issueSent = true;
							}
						} else {
							if (issueSent) {
								String iMsg = "AWT-Thread working";
								Session._log.info(iMsg);
								UIUtil.sendIssue("AWTHanging", iMsg);
								return;
							}
						}
					}
				}
			}, "AWT-WD");
			watchdog.setDaemon(true);
			watchdog.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected static String sendThreadDump() {
		ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
		for (ThreadInfo ti : threadMxBean.dumpAllThreads(true, true)) {
			if (ti.getThreadName() != null && ti.getThreadName().toLowerCase().startsWith("awt-ev")) {

				StringBuilder sb = new StringBuilder(
						"\"" + ti.getThreadName() + "\"" + " Id=" + ti.getThreadId() + " " + ti.getThreadState());
				if (ti.getLockName() != null) {
					sb.append(" on " + ti.getLockName());
				}
				if (ti.getLockOwnerName() != null) {
					sb.append(" owned by \"" + ti.getLockOwnerName() + "\" Id=" + ti.getLockOwnerId());
				}
				if (ti.isSuspended()) {
					sb.append(" (suspended)");
				}
				if (ti.isInNative()) {
					sb.append(" (in native)");
				}
				sb.append('\n');
				int i = 0;
				for (; i < ti.getStackTrace().length && i < 100; i++) {
					StackTraceElement ste = ti.getStackTrace()[i];
					sb.append("\tat " + ste.toString());
					sb.append('\n');
					if (i == 0 && ti.getLockInfo() != null) {
						Thread.State ts = ti.getThreadState();
						switch (ts) {<commit_msg>added TODO<commit_after>package net.sf.jailer.ui.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

import net.sf.jailer.database.Session;
import net.sf.jailer.ui.UIUtil;

public class AWTWatchdog {

	private static final long MAX_DELAY = 10000;

	public static void start() {
		try {
			Thread watchdog = new Thread(new Runnable() {
				@Override
				public void run() {
					boolean issueSent = false;
					for (;;) {
						try {
							long t = System.currentTimeMillis();
							Thread.sleep(1000);
							if (t + 5000 < System.currentTimeMillis()) {
								setStarttime(0);
								continue;
							}
						} catch (InterruptedException e) {
							// ignore
						}
						
						long st = getStarttime();
						if (st != 0 && st + MAX_DELAY < System.currentTimeMillis()) {
							if (!issueSent) {
								String dump;
								try {
									dump = sendThreadDump();
								} catch (Throwable t) {
									StringWriter sw = new StringWriter();
							        PrintWriter pw = new PrintWriter(sw);
							        t.printStackTrace(pw);
							        dump = sw.toString();
								}
								dump = "AWT-Thread hanging: " + dump;
								Session._log.error(dump);
								final int MAX_CL = 1000;
					            String iMsg = dump;
					            if (iMsg.length() > MAX_CL) {
					            	iMsg = iMsg.substring(0, MAX_CL);
					            }
								UIUtil.sendIssue("AWTHanging", iMsg);
								issueSent = true;
							}
						} else {
							if (issueSent) {
								String iMsg = "AWT-Thread working";
								Session._log.info(iMsg);
								UIUtil.sendIssue("AWTHanging", iMsg);
								return;
							}
						}
					}
				}
			}, "AWT-WD");
			watchdog.setDaemon(true);
			watchdog.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// TODO: show latest "net..jailer" + use invokelater-probes instead

	protected static String sendThreadDump() {
		ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
		for (ThreadInfo ti : threadMxBean.dumpAllThreads(true, true)) {
			if (ti.getThreadName() != null && ti.getThreadName().toLowerCase().startsWith("awt-ev")) {

				StringBuilder sb = new StringBuilder(
						"\"" + ti.getThreadName() + "\"" + " Id=" + ti.getThreadId() + " " + ti.getThreadState());
				if (ti.getLockName() != null) {
					sb.append(" on " + ti.getLockName());
				}
				if (ti.getLockOwnerName() != null) {
					sb.append(" owned by \"" + ti.getLockOwnerName() + "\" Id=" + ti.getLockOwnerId());
				}
				if (ti.isSuspended()) {
					sb.append(" (suspended)");
				}
				if (ti.isInNative()) {
					sb.append(" (in native)");
				}
				sb.append('\n');
				int i = 0;
				for (; i < ti.getStackTrace().length && i < 100; i++) {
					StackTraceElement ste = ti.getStackTrace()[i];
					sb.append("\tat " + ste.toString());
					sb.append('\n');
					if (i == 0 && ti.getLockInfo() != null) {
						Thread.State ts = ti.getThreadState();
						switch (ts) {
{'fraction_non_alphanumeric': 0.1480352846832398, 'fraction_numerical': 0.00801924619085806, 'mean_word_length': 2.2786540483701367, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2975168', 'n_tokens_mistral': 2767, 'n_tokens_neox': 1969, 'n_words': 420}