From df1c1316483a3c5be8432630367a1f842c0c3263 Mon Sep 17 00:00:00 2001 From: hns Date: Thu, 19 Feb 2004 14:12:39 +0000 Subject: [PATCH] cleanup in Application: * make init(), start() and stop() synchronized * suppress some logging messages if using default values (cache size, preallocated evaluators) * do not null out freeThreads stack in stop() so we don't have to worry about calling releaseEvaluator() in stopped applications * replace boolean stopped field with boolean running and add public synchronized isRunning() accessor * if preallocating multiple evaluators only init scripting engine on the first one * move invocation of onStart() from start() to scheduler thread --- src/helma/framework/core/Application.java | 71 ++++++++++--------- .../framework/core/RequestEvaluator.java | 4 +- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/helma/framework/core/Application.java b/src/helma/framework/core/Application.java index e23eba60..465da5b6 100644 --- a/src/helma/framework/core/Application.java +++ b/src/helma/framework/core/Application.java @@ -82,7 +82,7 @@ public final class Application implements IPathElement, Runnable { */ protected Stack freeThreads; protected Vector allThreads; - boolean stopped = false; + boolean running = false; boolean debug; long starttime; Hashtable sessions; @@ -273,7 +273,7 @@ public final class Application implements IPathElement, Runnable { /** * Get the application ready to run, initializing the evaluators and type manager. */ - public void init() + public synchronized void init() throws DatabaseException, ScriptingException, MalformedURLException { // create and init type mananger @@ -318,12 +318,16 @@ public final class Application implements IPathElement, Runnable { // not parsable as number, keep 0 } - logEvent("Starting "+minThreads+" evaluator(s) for " + name); + if (minThreads > 0) { + logEvent("Starting "+minThreads+" evaluator(s) for " + name); + } for (int i = 0; i < minThreads; i++) { RequestEvaluator ev = new RequestEvaluator(this); - ev.initScriptingEngine(); + if (i == 0) { + ev.initScriptingEngine(); + } freeThreads.push(ev); allThreads.addElement(ev); } @@ -363,24 +367,10 @@ public final class Application implements IPathElement, Runnable { /** * Create and start scheduler and cleanup thread */ - public void start() { + public synchronized void start() { starttime = System.currentTimeMillis(); - // read in standard prototypes to make first request go faster - // typemgr.updatePrototype("root"); - // typemgr.updatePrototype("global"); - - // as first thing, invoke global onStart() function - RequestEvaluator eval = getEvaluator(); - try { - eval.invokeInternal(null, "onStart", new Object[0]); - } catch (Exception ignore) { - logEvent("Error in " + name + "/onStart(): " + ignore); - } finally { - if (!stopped) { - releaseEvaluator(eval); - } - } + running = true; worker = new Thread(this, "Worker-" + name); worker.setPriority(Thread.NORM_PRIORITY + 1); @@ -390,8 +380,8 @@ public final class Application implements IPathElement, Runnable { /** * This is called to shut down a running application. */ - public void stop() { - stopped = true; + public synchronized void stop() { + running = false; // stop all threads, this app is going down if (worker != null) { @@ -411,7 +401,7 @@ public final class Application implements IPathElement, Runnable { // remove evaluators allThreads.removeAllElements(); - freeThreads = null; + freeThreads.clear(); // shut down node manager and embedded db try { @@ -441,11 +431,15 @@ public final class Application implements IPathElement, Runnable { } + public synchronized boolean isRunning() { + return running; + } + /** * Returns a free evaluator to handle a request. */ - protected RequestEvaluator getEvaluator() { - if (stopped) { + private RequestEvaluator getEvaluator() { + if (!running) { throw new ApplicationStoppedException(); } @@ -464,8 +458,8 @@ public final class Application implements IPathElement, Runnable { synchronized (this) { // allocate a new evaluator if (allThreads.size() < maxThreads) { - logEvent("Starting evaluator " + (allThreads.size() + 1) + - " for application " + name); + logEvent("Starting engine " + (allThreads.size() + 1) + + " for " + name); RequestEvaluator ev = new RequestEvaluator(this); @@ -1383,6 +1377,17 @@ public final class Application implements IPathElement, Runnable { * kicking out expired user sessions. */ public void run() { + + // as first thing, invoke global onStart() function + RequestEvaluator eval = getEvaluator(); + try { + eval.invokeInternal(null, "onStart", new Object[0]); + } catch (Exception xcept) { + logEvent("Error in " + name + "/onStart(): " + xcept); + } finally { + releaseEvaluator(eval); + } + // interval between session cleanups long sessionCleanupInterval = 60000; long lastSessionCleanup = System.currentTimeMillis(); @@ -1441,7 +1446,7 @@ public final class Application implements IPathElement, Runnable { logEvent("Error cleaning up sessions: " + cx); cx.printStackTrace(); } finally { - if (!stopped && thisEvaluator != null) { + if (thisEvaluator != null) { releaseEvaluator(thisEvaluator); } } @@ -1475,7 +1480,7 @@ public final class Application implements IPathElement, Runnable { try { thisEvaluator = getEvaluator(); } catch (RuntimeException rt) { - if (!stopped) { + if (running) { logEvent("couldn't execute " + j + ", maximum thread count reached"); @@ -1500,9 +1505,7 @@ public final class Application implements IPathElement, Runnable { } catch (Exception ex) { logEvent("error running " + j + ": " + ex.toString()); } finally { - if (!stopped) { - releaseEvaluator(thisEvaluator); - } + releaseEvaluator(thisEvaluator); } } } @@ -1956,9 +1959,7 @@ public final class Application implements IPathElement, Runnable { } catch (Exception ex) { // gets logged in RequestEvaluator } finally { - if (!stopped) { - releaseEvaluator(thisEvaluator); - } + releaseEvaluator(thisEvaluator); thisEvaluator = null; activeCronJobs.remove(job.getName()); } diff --git a/src/helma/framework/core/RequestEvaluator.java b/src/helma/framework/core/RequestEvaluator.java index 9ef91401..efbc8600 100644 --- a/src/helma/framework/core/RequestEvaluator.java +++ b/src/helma/framework/core/RequestEvaluator.java @@ -270,7 +270,7 @@ public final class RequestEvaluator implements Runnable { // specified in the property file. res.status = 404; - String notFoundAction = app.props.getProperty("notFound", + String notFoundAction = app.props.getProperty("notfound", "notfound"); currentElement = root; @@ -896,7 +896,7 @@ public final class RequestEvaluator implements Runnable { } private synchronized void checkThread() { - if (app.stopped) { + if (!app.isRunning()) { throw new ApplicationStoppedException(); }