/*********************************************************************************** * * Copyright (c) 2014 Kamil Baczkowicz * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * * The Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * * Kamil Baczkowicz - initial API and implementation and/or initial documentation * */ package pl.baczkowicz.spy.scripts; import java.util.concurrent.Executor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.baczkowicz.spy.eventbus.IKBus; import pl.baczkowicz.spy.utils.ThreadingUtils; import pl.baczkowicz.spy.utils.TimeUtils; /** * This class is used for detecting stalled/frozen scripts. */ public class ScriptHealthDetector implements Runnable { /** Default script/thread timeout - if not touched, the script will be reported as frozen. */ public final static int DEFAULT_THREAD_TIMEOUT = 5000; /** Diagnostic logger. */ private final static Logger logger = LoggerFactory.getLogger(ScriptHealthDetector.class); /** The script. */ private final Script script; /** Event bus. */ private IKBus eventBus; /** Executor. */ private Executor executor; /** * Creates a ScriptHealthDetector. * * @param eventBus The event bus to use * @param script The script * @param executor The executor to use */ public ScriptHealthDetector(final IKBus eventBus, final Script script, final Executor executor) { this.script = script; this.eventBus = eventBus; this.executor = executor; } /** * This is expected to run as long as a script is running. */ public void run() { ThreadingUtils.logThreadStarting("Script Health Detector"); while (script.getStatus().equals(ScriptRunningState.RUNNING)) { if (logger.isTraceEnabled()) { logger.trace("Checking script {} for responsiveness, last touch = {}, timeout = {}, current time = {}", script.getName(), script.getLastTouch(), script.getScriptTimeout(), TimeUtils.getMonotonicTime()); } if (script.getLastTouch() + script.getScriptTimeout() < TimeUtils.getMonotonicTime()) { logger.warn("Script {} detected as frozen, last touch = {}, current time = {}", script.getName(), script.getLastTouch(), TimeUtils.getMonotonicTime()); ScriptRunner.changeState(eventBus, script.getName(), ScriptRunningState.FROZEN, script, executor); } if (ThreadingUtils.sleep(1000)) { break; } } // TODO: what if it freezes for the second time in the same run? ThreadingUtils.logThreadEnding(); } }