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
This commit is contained in:
parent
7bfb70430e
commit
df1c131648
2 changed files with 38 additions and 37 deletions
|
@ -82,7 +82,7 @@ public final class Application implements IPathElement, Runnable {
|
||||||
*/
|
*/
|
||||||
protected Stack freeThreads;
|
protected Stack freeThreads;
|
||||||
protected Vector allThreads;
|
protected Vector allThreads;
|
||||||
boolean stopped = false;
|
boolean running = false;
|
||||||
boolean debug;
|
boolean debug;
|
||||||
long starttime;
|
long starttime;
|
||||||
Hashtable sessions;
|
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.
|
* Get the application ready to run, initializing the evaluators and type manager.
|
||||||
*/
|
*/
|
||||||
public void init()
|
public synchronized void init()
|
||||||
throws DatabaseException, ScriptingException, MalformedURLException {
|
throws DatabaseException, ScriptingException, MalformedURLException {
|
||||||
|
|
||||||
// create and init type mananger
|
// create and init type mananger
|
||||||
|
@ -318,12 +318,16 @@ public final class Application implements IPathElement, Runnable {
|
||||||
// not parsable as number, keep 0
|
// 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++) {
|
for (int i = 0; i < minThreads; i++) {
|
||||||
RequestEvaluator ev = new RequestEvaluator(this);
|
RequestEvaluator ev = new RequestEvaluator(this);
|
||||||
|
|
||||||
ev.initScriptingEngine();
|
if (i == 0) {
|
||||||
|
ev.initScriptingEngine();
|
||||||
|
}
|
||||||
freeThreads.push(ev);
|
freeThreads.push(ev);
|
||||||
allThreads.addElement(ev);
|
allThreads.addElement(ev);
|
||||||
}
|
}
|
||||||
|
@ -363,24 +367,10 @@ public final class Application implements IPathElement, Runnable {
|
||||||
/**
|
/**
|
||||||
* Create and start scheduler and cleanup thread
|
* Create and start scheduler and cleanup thread
|
||||||
*/
|
*/
|
||||||
public void start() {
|
public synchronized void start() {
|
||||||
starttime = System.currentTimeMillis();
|
starttime = System.currentTimeMillis();
|
||||||
|
|
||||||
// read in standard prototypes to make first request go faster
|
running = true;
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
worker = new Thread(this, "Worker-" + name);
|
worker = new Thread(this, "Worker-" + name);
|
||||||
worker.setPriority(Thread.NORM_PRIORITY + 1);
|
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.
|
* This is called to shut down a running application.
|
||||||
*/
|
*/
|
||||||
public void stop() {
|
public synchronized void stop() {
|
||||||
stopped = true;
|
running = false;
|
||||||
|
|
||||||
// stop all threads, this app is going down
|
// stop all threads, this app is going down
|
||||||
if (worker != null) {
|
if (worker != null) {
|
||||||
|
@ -411,7 +401,7 @@ public final class Application implements IPathElement, Runnable {
|
||||||
|
|
||||||
// remove evaluators
|
// remove evaluators
|
||||||
allThreads.removeAllElements();
|
allThreads.removeAllElements();
|
||||||
freeThreads = null;
|
freeThreads.clear();
|
||||||
|
|
||||||
// shut down node manager and embedded db
|
// shut down node manager and embedded db
|
||||||
try {
|
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.
|
* Returns a free evaluator to handle a request.
|
||||||
*/
|
*/
|
||||||
protected RequestEvaluator getEvaluator() {
|
private RequestEvaluator getEvaluator() {
|
||||||
if (stopped) {
|
if (!running) {
|
||||||
throw new ApplicationStoppedException();
|
throw new ApplicationStoppedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,8 +458,8 @@ public final class Application implements IPathElement, Runnable {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
// allocate a new evaluator
|
// allocate a new evaluator
|
||||||
if (allThreads.size() < maxThreads) {
|
if (allThreads.size() < maxThreads) {
|
||||||
logEvent("Starting evaluator " + (allThreads.size() + 1) +
|
logEvent("Starting engine " + (allThreads.size() + 1) +
|
||||||
" for application " + name);
|
" for " + name);
|
||||||
|
|
||||||
RequestEvaluator ev = new RequestEvaluator(this);
|
RequestEvaluator ev = new RequestEvaluator(this);
|
||||||
|
|
||||||
|
@ -1383,6 +1377,17 @@ public final class Application implements IPathElement, Runnable {
|
||||||
* kicking out expired user sessions.
|
* kicking out expired user sessions.
|
||||||
*/
|
*/
|
||||||
public void run() {
|
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
|
// interval between session cleanups
|
||||||
long sessionCleanupInterval = 60000;
|
long sessionCleanupInterval = 60000;
|
||||||
long lastSessionCleanup = System.currentTimeMillis();
|
long lastSessionCleanup = System.currentTimeMillis();
|
||||||
|
@ -1441,7 +1446,7 @@ public final class Application implements IPathElement, Runnable {
|
||||||
logEvent("Error cleaning up sessions: " + cx);
|
logEvent("Error cleaning up sessions: " + cx);
|
||||||
cx.printStackTrace();
|
cx.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
if (!stopped && thisEvaluator != null) {
|
if (thisEvaluator != null) {
|
||||||
releaseEvaluator(thisEvaluator);
|
releaseEvaluator(thisEvaluator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1475,7 +1480,7 @@ public final class Application implements IPathElement, Runnable {
|
||||||
try {
|
try {
|
||||||
thisEvaluator = getEvaluator();
|
thisEvaluator = getEvaluator();
|
||||||
} catch (RuntimeException rt) {
|
} catch (RuntimeException rt) {
|
||||||
if (!stopped) {
|
if (running) {
|
||||||
logEvent("couldn't execute " + j +
|
logEvent("couldn't execute " + j +
|
||||||
", maximum thread count reached");
|
", maximum thread count reached");
|
||||||
|
|
||||||
|
@ -1500,9 +1505,7 @@ public final class Application implements IPathElement, Runnable {
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logEvent("error running " + j + ": " + ex.toString());
|
logEvent("error running " + j + ": " + ex.toString());
|
||||||
} finally {
|
} finally {
|
||||||
if (!stopped) {
|
releaseEvaluator(thisEvaluator);
|
||||||
releaseEvaluator(thisEvaluator);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1956,9 +1959,7 @@ public final class Application implements IPathElement, Runnable {
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
// gets logged in RequestEvaluator
|
// gets logged in RequestEvaluator
|
||||||
} finally {
|
} finally {
|
||||||
if (!stopped) {
|
releaseEvaluator(thisEvaluator);
|
||||||
releaseEvaluator(thisEvaluator);
|
|
||||||
}
|
|
||||||
thisEvaluator = null;
|
thisEvaluator = null;
|
||||||
activeCronJobs.remove(job.getName());
|
activeCronJobs.remove(job.getName());
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,7 +270,7 @@ public final class RequestEvaluator implements Runnable {
|
||||||
// specified in the property file.
|
// specified in the property file.
|
||||||
res.status = 404;
|
res.status = 404;
|
||||||
|
|
||||||
String notFoundAction = app.props.getProperty("notFound",
|
String notFoundAction = app.props.getProperty("notfound",
|
||||||
"notfound");
|
"notfound");
|
||||||
|
|
||||||
currentElement = root;
|
currentElement = root;
|
||||||
|
@ -896,7 +896,7 @@ public final class RequestEvaluator implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void checkThread() {
|
private synchronized void checkThread() {
|
||||||
if (app.stopped) {
|
if (!app.isRunning()) {
|
||||||
throw new ApplicationStoppedException();
|
throw new ApplicationStoppedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue