Threads and evaluators are now started in lazy mode - only when needed. Halleluja!
This commit is contained in:
parent
73bcc24ffc
commit
6d0491e2de
12 changed files with 396 additions and 235 deletions
|
@ -8,6 +8,13 @@ import java.io.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.objectmodel.IServer;
|
import helma.objectmodel.IServer;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
|
import FESI.Parser.*;
|
||||||
|
import FESI.AST.ASTFormalParameterList;
|
||||||
|
import FESI.AST.ASTStatementList;
|
||||||
|
import FESI.AST.EcmaScriptTreeConstants;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,34 +27,40 @@ import FESI.Data.*;
|
||||||
public class Action {
|
public class Action {
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
String functionName;
|
|
||||||
Prototype prototype;
|
Prototype prototype;
|
||||||
Application app;
|
Application app;
|
||||||
|
File file;
|
||||||
long lastmod;
|
long lastmod;
|
||||||
|
|
||||||
|
|
||||||
|
ParsedFunction pfunc;
|
||||||
|
|
||||||
|
|
||||||
public Action (File file, String name, Prototype proto) {
|
public Action (File file, String name, Prototype proto) {
|
||||||
this.prototype = proto;
|
this.prototype = proto;
|
||||||
this.app = proto.app;
|
this.app = proto.app;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.file = file;
|
||||||
update (file);
|
update (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void update (File f) {
|
public void update (File f) {
|
||||||
|
|
||||||
long fmod = f.lastModified ();
|
this.file = f;
|
||||||
|
long fmod = file.lastModified ();
|
||||||
if (lastmod == fmod)
|
if (lastmod == fmod)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileReader reader = new FileReader (f);
|
FileReader reader = new FileReader (file);
|
||||||
char cbuf[] = new char[(int)f.length ()];
|
char cbuf[] = new char[(int) file.length ()];
|
||||||
reader.read (cbuf);
|
reader.read (cbuf);
|
||||||
reader.close ();
|
reader.close ();
|
||||||
String content = new String (cbuf);
|
String content = new String (cbuf);
|
||||||
update (content);
|
update (content);
|
||||||
} catch (Exception filex) {
|
} catch (Exception filex) {
|
||||||
IServer.getLogger().log ("*** Error reading template file "+f+": "+filex);
|
IServer.getLogger().log ("*** Error reading action file "+file+": "+filex);
|
||||||
}
|
}
|
||||||
lastmod = fmod;
|
lastmod = fmod;
|
||||||
}
|
}
|
||||||
|
@ -57,13 +70,13 @@ public class Action {
|
||||||
public void update (String content) throws Exception {
|
public void update (String content) throws Exception {
|
||||||
// IServer.getLogger().log ("Reading text template " + name);
|
// IServer.getLogger().log ("Reading text template " + name);
|
||||||
|
|
||||||
functionName = name+"_hop_action";
|
String fname = name+"_hop_action";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.typemgr.readFunction (functionName, "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", content, prototype.getName ());
|
pfunc = parseFunction (fname, "arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10", content);
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
String message = x.getMessage ();
|
String message = x.getMessage ();
|
||||||
app.typemgr.generateErrorFeedback (functionName, message, prototype.getName ());
|
app.typemgr.generateErrorFeedback (fname, message, prototype.getName ());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,9 +87,97 @@ public class Action {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFunctionName () {
|
public String getFunctionName () {
|
||||||
return functionName;
|
return pfunc.functionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ParsedFunction parseFunction (String funcname, String params, String body) throws EcmaScriptException {
|
||||||
|
|
||||||
|
// ESObject fp = app.eval.evaluator.getFunctionPrototype();
|
||||||
|
// ConstructedFunctionObject function = null;
|
||||||
|
ASTFormalParameterList fpl = null;
|
||||||
|
ASTStatementList sl = null;
|
||||||
|
FunctionEvaluationSource fes = null;
|
||||||
|
|
||||||
|
if (body == null || "".equals (body.trim()))
|
||||||
|
body = ";\r\n";
|
||||||
|
else
|
||||||
|
body = body + "\r\n";
|
||||||
|
if (params == null) params = "";
|
||||||
|
else params = params.trim ();
|
||||||
|
|
||||||
|
String fulltext = "function "+funcname+" (" + params + ") {\n" + body + "\n}";
|
||||||
|
|
||||||
|
EcmaScript parser;
|
||||||
|
StringReader is;
|
||||||
|
|
||||||
|
// Special case for empty parameters
|
||||||
|
if (params.length()==0) {
|
||||||
|
fpl = new ASTFormalParameterList(EcmaScriptTreeConstants.JJTFORMALPARAMETERLIST);
|
||||||
|
} else {
|
||||||
|
is = new java.io.StringReader(params);
|
||||||
|
parser = new EcmaScript(is);
|
||||||
|
try {
|
||||||
|
fpl = (ASTFormalParameterList) parser.FormalParameterList();
|
||||||
|
is.close();
|
||||||
|
} catch (ParseException x) {
|
||||||
|
throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this is very very very strange: without the toString, lots of obscure exceptions
|
||||||
|
// deep inside the parser...
|
||||||
|
is = new java.io.StringReader(body.toString ());
|
||||||
|
try {
|
||||||
|
parser = new EcmaScript (is);
|
||||||
|
sl = (ASTStatementList) parser.StatementList();
|
||||||
|
is.close();
|
||||||
|
} catch (ParseException x) {
|
||||||
|
IServer.getLogger().log ("Error parsing file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+x);
|
||||||
|
throw new EcmaScriptParseException (x, new StringEvaluationSource(fulltext, null));
|
||||||
|
} catch (Exception x) {
|
||||||
|
IServer.getLogger().log ("Error parsing file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+x);
|
||||||
|
throw new RuntimeException (x.getMessage ());
|
||||||
|
}
|
||||||
|
|
||||||
|
fes = new FunctionEvaluationSource (new StringEvaluationSource(fulltext, null), funcname);
|
||||||
|
return new ParsedFunction (fpl, sl, fes, fulltext, funcname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||||
|
if (pfunc != null)
|
||||||
|
pfunc.updateRequestEvaluator (reval);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ParsedFunction {
|
||||||
|
|
||||||
|
ASTFormalParameterList fpl = null;
|
||||||
|
ASTStatementList sl = null;
|
||||||
|
FunctionEvaluationSource fes = null;
|
||||||
|
String fullFunctionText = null;
|
||||||
|
String functionName;
|
||||||
|
|
||||||
|
public ParsedFunction (ASTFormalParameterList fpl, ASTStatementList sl, FunctionEvaluationSource fes,
|
||||||
|
String fullFunctionText, String functionName) {
|
||||||
|
this.fpl = fpl;
|
||||||
|
this.sl = sl;
|
||||||
|
this.fes = fes;
|
||||||
|
this.fullFunctionText = fullFunctionText;
|
||||||
|
this.functionName = functionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||||
|
|
||||||
|
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||||
|
|
||||||
|
EcmaScriptVariableVisitor vdvisitor = reval.evaluator.getVarDeclarationVisitor();
|
||||||
|
Vector vnames = vdvisitor.processVariableDeclarations(sl, fes);
|
||||||
|
|
||||||
|
FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction (
|
||||||
|
reval.evaluator, functionName, fes,
|
||||||
|
fullFunctionText, fpl.getArguments(), vnames, sl);
|
||||||
|
op.putHiddenProperty (functionName, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
|
||||||
TypeManager typemgr;
|
TypeManager typemgr;
|
||||||
|
|
||||||
RequestEvaluator eval;
|
RequestEvaluator eval;
|
||||||
private Stack freeThreads;
|
protected Stack freeThreads;
|
||||||
protected Vector allThreads;
|
protected Vector allThreads;
|
||||||
|
|
||||||
Hashtable sessions;
|
Hashtable sessions;
|
||||||
|
@ -154,7 +154,7 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
|
||||||
if (allThreads != null) {
|
if (allThreads != null) {
|
||||||
for (Enumeration e=allThreads.elements (); e.hasMoreElements (); ) {
|
for (Enumeration e=allThreads.elements (); e.hasMoreElements (); ) {
|
||||||
RequestEvaluator ev = (RequestEvaluator) e.nextElement ();
|
RequestEvaluator ev = (RequestEvaluator) e.nextElement ();
|
||||||
ev.stop ();
|
ev.stopThread ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allThreads.removeAllElements ();
|
allThreads.removeAllElements ();
|
||||||
|
@ -166,20 +166,49 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized RequestEvaluator getEvaluator () {
|
protected RequestEvaluator getEvaluator () {
|
||||||
if (freeThreads == null)
|
if (freeThreads == null)
|
||||||
throw new ApplicationStoppedException ();
|
throw new ApplicationStoppedException ();
|
||||||
if (freeThreads.empty ())
|
try {
|
||||||
|
return (RequestEvaluator) freeThreads.pop ();
|
||||||
|
} catch (EmptyStackException nothreads) {
|
||||||
throw new RuntimeException ("Maximum Thread count reached.");
|
throw new RuntimeException ("Maximum Thread count reached.");
|
||||||
RequestEvaluator ev = (RequestEvaluator) freeThreads.pop ();
|
}
|
||||||
return ev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void releaseEvaluator (RequestEvaluator ev) {
|
protected void releaseEvaluator (RequestEvaluator ev) {
|
||||||
if (ev != null)
|
if (ev != null)
|
||||||
freeThreads.push (ev);
|
freeThreads.push (ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean setNumberOfEvaluators (int n) {
|
||||||
|
if (n < 1 || n > 512)
|
||||||
|
return false;
|
||||||
|
int current = allThreads.size();
|
||||||
|
synchronized (allThreads) {
|
||||||
|
if (n > current) {
|
||||||
|
int toBeCreated = n - current;
|
||||||
|
for (int i=0; i<toBeCreated; i++) {
|
||||||
|
RequestEvaluator ev = new RequestEvaluator (this);
|
||||||
|
freeThreads.push (ev);
|
||||||
|
allThreads.addElement (ev);
|
||||||
|
}
|
||||||
|
} else if (n < current) {
|
||||||
|
int toBeDestroyed = current - n;
|
||||||
|
for (int i=0; i<toBeDestroyed; i++) {
|
||||||
|
try {
|
||||||
|
RequestEvaluator re = (RequestEvaluator) freeThreads.pop ();
|
||||||
|
allThreads.removeElement (re);
|
||||||
|
re.stopThread ();
|
||||||
|
} catch (EmptyStackException empty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public ResponseTrans execute (RequestTrans req) {
|
public ResponseTrans execute (RequestTrans req) {
|
||||||
|
|
||||||
requestCount += 1;
|
requestCount += 1;
|
||||||
|
@ -243,8 +272,6 @@ public class Application extends UnicastRemoteObject implements IRemoteApp, Runn
|
||||||
}
|
}
|
||||||
|
|
||||||
public Prototype getPrototype (String str) {
|
public Prototype getPrototype (String str) {
|
||||||
if (debug)
|
|
||||||
IServer.getLogger().log ("retrieving prototype for name "+str);
|
|
||||||
return typemgr.getPrototype (str);
|
return typemgr.getPrototype (str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ package helma.framework.core;
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
import FESI.Exceptions.*;
|
import FESI.Exceptions.*;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
|
import FESI.Interpreter.Evaluator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ESApp represents the app node of an application, providing an app-wide transient shared
|
* ESApp represents the app node of an application, providing an app-wide transient shared
|
||||||
|
@ -17,10 +18,15 @@ public class ESAppNode extends ESNode {
|
||||||
private Application app;
|
private Application app;
|
||||||
private DatePrototype createtime;
|
private DatePrototype createtime;
|
||||||
|
|
||||||
public ESAppNode (INode node, RequestEvaluator eval) {
|
public ESAppNode (INode node, RequestEvaluator eval) throws EcmaScriptException {
|
||||||
super (eval.esNodePrototype, eval.evaluator, node, eval);
|
super (eval.esNodePrototype, eval.evaluator, node, eval);
|
||||||
app = eval.app;
|
app = eval.app;
|
||||||
createtime = new DatePrototype (eval.evaluator, node.created());
|
createtime = new DatePrototype (eval.evaluator, node.created());
|
||||||
|
FunctionPrototype fp = (FunctionPrototype) eval.evaluator.getFunctionPrototype();
|
||||||
|
putHiddenProperty("countEvaluators", new AppCountEvaluators ("countEvaluators", evaluator, fp));
|
||||||
|
putHiddenProperty("countFreeEvaluators", new AppCountFreeEvaluators ("countFreeEvaluators", evaluator, fp));
|
||||||
|
putHiddenProperty("countBusyEvaluators", new AppCountBusyEvaluators ("countBusyEvaluators", evaluator, fp));
|
||||||
|
putHiddenProperty("setNumberOfEvaluators", new AppSetNumberOfEvaluators ("setNumberOfEvaluators", evaluator, fp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,6 +49,47 @@ public class ESAppNode extends ESNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class AppCountEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppCountEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.allThreads.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppCountFreeEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppCountFreeEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.freeThreads.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppCountBusyEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppCountBusyEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 0);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
return new ESNumber (app.allThreads.size() - app.freeThreads.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppSetNumberOfEvaluators extends BuiltinFunctionObject {
|
||||||
|
AppSetNumberOfEvaluators (String name, Evaluator evaluator, FunctionPrototype fp) {
|
||||||
|
super (fp, evaluator, name, 1);
|
||||||
|
}
|
||||||
|
public ESValue callFunction (ESObject thisObject, ESValue[] arguments) throws EcmaScriptException {
|
||||||
|
RequestEvaluator ev = new RequestEvaluator (app);
|
||||||
|
if (arguments.length != 1)
|
||||||
|
return ESBoolean.makeBoolean (false);
|
||||||
|
return ESBoolean.makeBoolean (app.setNumberOfEvaluators (arguments[0].toInt32()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String toString () {
|
public String toString () {
|
||||||
return ("AppNode "+node.getNameOrID ());
|
return ("AppNode "+node.getNameOrID ());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ package helma.framework.core;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
|
import helma.objectmodel.IServer;
|
||||||
|
import FESI.Data.ObjectPrototype;
|
||||||
|
import FESI.Exceptions.EcmaScriptException;
|
||||||
|
import FESI.Interpreter.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,24 +22,51 @@ public class FunctionFile {
|
||||||
String name;
|
String name;
|
||||||
Prototype prototype;
|
Prototype prototype;
|
||||||
Application app;
|
Application app;
|
||||||
|
File file;
|
||||||
long lastmod;
|
long lastmod;
|
||||||
|
|
||||||
public FunctionFile (File file, String name, Prototype proto) {
|
public FunctionFile (File file, String name, Prototype proto) {
|
||||||
this.prototype = proto;
|
this.prototype = proto;
|
||||||
this.app = proto.app;
|
this.app = proto.app;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.file = file;
|
||||||
update (file);
|
update (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void update (File f) {
|
public void update (File f) {
|
||||||
|
|
||||||
long fmod = f.lastModified ();
|
this.file = f;
|
||||||
|
|
||||||
|
long fmod = file.lastModified ();
|
||||||
if (lastmod == fmod)
|
if (lastmod == fmod)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lastmod = fmod;
|
lastmod = fmod;
|
||||||
app.typemgr.readFunctionFile (f, prototype.getName ());
|
// app.typemgr.readFunctionFile (file, prototype.getName ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRequestEvaluator (RequestEvaluator reval) {
|
||||||
|
|
||||||
|
EvaluationSource es = new FileEvaluationSource(file.getPath(), null);
|
||||||
|
FileReader fr = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fr = new FileReader(file);
|
||||||
|
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||||
|
reval.evaluator.evaluate(fr, op, es, false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
IServer.getLogger().log ("Error parsing function file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+e);
|
||||||
|
} catch (EcmaScriptException e) {
|
||||||
|
IServer.getLogger().log ("Error parsing function file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+e);
|
||||||
|
} finally {
|
||||||
|
if (fr!=null) {
|
||||||
|
try {
|
||||||
|
fr.close();
|
||||||
|
} catch (IOException ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
|
import FESI.Exceptions.EcmaScriptException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,6 +120,24 @@ public class Prototype {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void initRequestEvaluator (RequestEvaluator reval) {
|
||||||
|
for (Enumeration en = functions.elements(); en.hasMoreElements(); ) {
|
||||||
|
FunctionFile ff = (FunctionFile) en.nextElement ();
|
||||||
|
ff.updateRequestEvaluator (reval);
|
||||||
|
}
|
||||||
|
for (Enumeration en = templates.elements(); en.hasMoreElements(); ) {
|
||||||
|
Template tmp = (Template) en.nextElement ();
|
||||||
|
try {
|
||||||
|
tmp.updateRequestEvaluator (reval);
|
||||||
|
} catch (EcmaScriptException ignore) {}
|
||||||
|
}
|
||||||
|
for (Enumeration en = actions.elements(); en.hasMoreElements(); ) {
|
||||||
|
Action act = (Action) en.nextElement ();
|
||||||
|
try {
|
||||||
|
act.updateRequestEvaluator (reval);
|
||||||
|
} catch (EcmaScriptException ignore) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class RequestEvaluator implements Runnable {
|
||||||
this.objectcache = new LruHashtable (100, .80f);
|
this.objectcache = new LruHashtable (100, .80f);
|
||||||
this.prototypes = new Hashtable ();
|
this.prototypes = new Hashtable ();
|
||||||
initEvaluator ();
|
initEvaluator ();
|
||||||
startThread ();
|
// startThread ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,30 +119,25 @@ public class RequestEvaluator implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void startThread () {
|
/* private void startThread () {
|
||||||
rtx = new Transactor (this, app.nmgr);
|
rtx = new Transactor (this, app.nmgr);
|
||||||
evaluator.thread = rtx;
|
evaluator.thread = rtx;
|
||||||
rtx.start ();
|
rtx.start ();
|
||||||
// yield to make sure the transactor thread reaches waiting status before the first
|
// yield to make sure the transactor thread reaches waiting status before the first
|
||||||
// invocation request comes in
|
// invocation request comes in
|
||||||
Thread.yield ();
|
Thread.yield ();
|
||||||
}
|
} */
|
||||||
|
|
||||||
public void run () {
|
public void run () {
|
||||||
|
|
||||||
int txcount = 0;
|
int txcount = 0;
|
||||||
|
|
||||||
while (evaluator.thread == Thread.currentThread () && evaluator.thread == rtx) {
|
if (prototypes.size() == 0)
|
||||||
|
app.typemgr.initRequestEvaluator (this);
|
||||||
|
|
||||||
synchronized (this) {
|
do {
|
||||||
notifyAll ();
|
|
||||||
try {
|
|
||||||
wait ();
|
|
||||||
} catch (InterruptedException ir) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// make sure there is only one thread running per instance of this class
|
||||||
if (Thread.currentThread () != rtx)
|
if (Thread.currentThread () != rtx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -166,11 +161,6 @@ public class RequestEvaluator implements Runnable {
|
||||||
rtx.timer.beginEvent (requestPath+" init");
|
rtx.timer.beginEvent (requestPath+" init");
|
||||||
rtx.begin (requestPath);
|
rtx.begin (requestPath);
|
||||||
|
|
||||||
if (app.debug) {
|
|
||||||
IServer.getLogger().log ("request transactor = "+this);
|
|
||||||
IServer.getLogger().log ("user = "+user);
|
|
||||||
}
|
|
||||||
|
|
||||||
Action action = null;
|
Action action = null;
|
||||||
|
|
||||||
root = app.getDataRoot ();
|
root = app.getDataRoot ();
|
||||||
|
@ -187,11 +177,6 @@ public class RequestEvaluator implements Runnable {
|
||||||
reqData.setData (req.getReqData());
|
reqData.setData (req.getReqData());
|
||||||
req.data = reqData;
|
req.data = reqData;
|
||||||
|
|
||||||
if (app.debug) {
|
|
||||||
IServer.getLogger().log ("root = "+root);
|
|
||||||
IServer.getLogger().log ("usernode = "+esu);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
if (req.path == null || "".equals (req.path.trim ())) {
|
if (req.path == null || "".equals (req.path.trim ())) {
|
||||||
|
@ -454,33 +439,35 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
// create a new Thread every 1000 requests. The current one will fade out
|
// create a new Thread every 1000 requests. The current one will fade out
|
||||||
if (txcount++ > 1000) {
|
if (txcount++ > 1000) {
|
||||||
rtx.cleanup (); // close sql connections held by this thread
|
stopThread (); // stop thread - a new one will be created when needed
|
||||||
startThread ();
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// IServer.getLogger().log (this+ " exiting.");
|
synchronized (this) {
|
||||||
|
notifyAll ();
|
||||||
|
try {
|
||||||
|
wait ();
|
||||||
|
} catch (InterruptedException ir) {
|
||||||
|
Thread.currentThread ().interrupt ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (evaluator.thread == Thread.currentThread () && evaluator.thread == rtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ResponseTrans invoke (RequestTrans req, User user) throws Exception {
|
public synchronized ResponseTrans invoke (RequestTrans req, User user) throws Exception {
|
||||||
checkThread ();
|
|
||||||
this.reqtype = HTTP;
|
this.reqtype = HTTP;
|
||||||
this.req = req;
|
this.req = req;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.res = new ResponseTrans ();
|
this.res = new ResponseTrans ();
|
||||||
|
|
||||||
notifyAll ();
|
checkThread ();
|
||||||
wait (app.requestTimeout);
|
wait (app.requestTimeout);
|
||||||
if (reqtype > 0) {
|
if (reqtype > 0) {
|
||||||
IServer.getLogger().log ("Stopping Thread for Request "+app.getName()+"/"+req.path);
|
IServer.getLogger().log ("Stopping Thread for Request "+app.getName()+"/"+req.path);
|
||||||
evaluator.thread = null;
|
stopThread ();
|
||||||
rtx.kill ();
|
|
||||||
res.reset ();
|
res.reset ();
|
||||||
res.write ("<b>Error in application '"+app.getName()+"':</b> <br><br><pre>Request timed out.</pre>");
|
res.write ("<b>Error in application '"+app.getName()+"':</b> <br><br><pre>Request timed out.</pre>");
|
||||||
rtx = new Transactor (this, app.nmgr);
|
|
||||||
evaluator.thread = rtx;
|
|
||||||
rtx.start ();
|
|
||||||
Thread.yield ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -488,7 +475,6 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
|
|
||||||
public synchronized Object invokeXmlRpc (String method, Vector args) throws Exception {
|
public synchronized Object invokeXmlRpc (String method, Vector args) throws Exception {
|
||||||
checkThread ();
|
|
||||||
this.reqtype = XMLRPC;
|
this.reqtype = XMLRPC;
|
||||||
this.user = null;
|
this.user = null;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
@ -496,16 +482,10 @@ public class RequestEvaluator implements Runnable {
|
||||||
result = null;
|
result = null;
|
||||||
exception = null;
|
exception = null;
|
||||||
|
|
||||||
notifyAll ();
|
checkThread ();
|
||||||
wait (app.requestTimeout);
|
wait (app.requestTimeout);
|
||||||
if (reqtype > 0) {
|
if (reqtype > 0) {
|
||||||
IServer.getLogger().log ("Stopping Thread");
|
stopThread ();
|
||||||
evaluator.thread = null;
|
|
||||||
rtx.kill ();
|
|
||||||
rtx = new Transactor (this, app.nmgr);
|
|
||||||
evaluator.thread = rtx;
|
|
||||||
rtx.start ();
|
|
||||||
Thread.yield ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
|
@ -525,7 +505,6 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
public synchronized ESValue invokeFunction (ESObject obj, String functionName, ESValue[] args)
|
public synchronized ESValue invokeFunction (ESObject obj, String functionName, ESValue[] args)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
checkThread ();
|
|
||||||
this.reqtype = INTERNAL;
|
this.reqtype = INTERNAL;
|
||||||
this.user = null;
|
this.user = null;
|
||||||
this.current = obj;
|
this.current = obj;
|
||||||
|
@ -534,17 +513,11 @@ public class RequestEvaluator implements Runnable {
|
||||||
esresult = ESNull.theNull;
|
esresult = ESNull.theNull;
|
||||||
exception = null;
|
exception = null;
|
||||||
|
|
||||||
notifyAll ();
|
checkThread ();
|
||||||
wait (60000l*15); // give internal call more time (15 minutes) to complete
|
wait (60000l*15); // give internal call more time (15 minutes) to complete
|
||||||
|
|
||||||
if (reqtype > 0) {
|
if (reqtype > 0) {
|
||||||
IServer.getLogger().log ("Stopping Thread");
|
stopThread ();
|
||||||
evaluator.thread = null;
|
|
||||||
rtx.kill ();
|
|
||||||
rtx = new Transactor (this, app.nmgr);
|
|
||||||
evaluator.thread = rtx;
|
|
||||||
rtx.start ();
|
|
||||||
Thread.yield ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
|
@ -554,7 +527,6 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
public synchronized ESValue invokeFunction (User user, String functionName, ESValue[] args)
|
public synchronized ESValue invokeFunction (User user, String functionName, ESValue[] args)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
checkThread ();
|
|
||||||
this.reqtype = INTERNAL;
|
this.reqtype = INTERNAL;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
this.current = null;
|
this.current = null;
|
||||||
|
@ -563,17 +535,11 @@ public class RequestEvaluator implements Runnable {
|
||||||
esresult = ESNull.theNull;
|
esresult = ESNull.theNull;
|
||||||
exception = null;
|
exception = null;
|
||||||
|
|
||||||
notifyAll ();
|
checkThread ();
|
||||||
wait (app.requestTimeout);
|
wait (app.requestTimeout);
|
||||||
|
|
||||||
if (reqtype > 0) {
|
if (reqtype > 0) {
|
||||||
IServer.getLogger().log ("Stopping Thread");
|
stopThread ();
|
||||||
evaluator.thread = null;
|
|
||||||
rtx.kill ();
|
|
||||||
rtx = new Transactor (this, app.nmgr);
|
|
||||||
evaluator.thread = rtx;
|
|
||||||
rtx.start ();
|
|
||||||
Thread.yield ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
|
@ -583,24 +549,32 @@ public class RequestEvaluator implements Runnable {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop this request evaluator. If currently active kill the request, otherwise just
|
* Stop this request evaluator's current thread. If currently active kill the request, otherwise just
|
||||||
* notify.
|
* notify.
|
||||||
*/
|
*/
|
||||||
public synchronized void stop () {
|
public synchronized void stopThread () {
|
||||||
|
// IServer.getLogger().log ("Stopping Thread");
|
||||||
evaluator.thread = null;
|
evaluator.thread = null;
|
||||||
if (reqtype != NONE) {
|
Transactor t = rtx;
|
||||||
rtx.kill ();
|
rtx = null;
|
||||||
} else {
|
if (t != null) {
|
||||||
notifyAll ();
|
if (reqtype != NONE) {
|
||||||
|
t.kill ();
|
||||||
|
} else {
|
||||||
|
notifyAll ();
|
||||||
|
}
|
||||||
|
t.cleanup ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkThread () {
|
private synchronized void checkThread () throws InterruptedException {
|
||||||
if (rtx == null || !rtx.isAlive()) {
|
if (rtx == null || !rtx.isAlive()) {
|
||||||
|
// IServer.getLogger().log ("Starting Thread");
|
||||||
rtx = new Transactor (this, app.nmgr);
|
rtx = new Transactor (this, app.nmgr);
|
||||||
evaluator.thread = rtx;
|
evaluator.thread = rtx;
|
||||||
rtx.start ();
|
rtx.start ();
|
||||||
Thread.yield ();
|
} else {
|
||||||
|
notifyAll ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import FESI.Data.*;
|
import FESI.Data.*;
|
||||||
|
import FESI.Exceptions.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +23,9 @@ import FESI.Data.*;
|
||||||
|
|
||||||
public class Template extends Action {
|
public class Template extends Action {
|
||||||
|
|
||||||
|
ParsedFunction psfunc;
|
||||||
|
|
||||||
|
|
||||||
public Template (File file, String name, Prototype proto) {
|
public Template (File file, String name, Prototype proto) {
|
||||||
super (file, name, proto);
|
super (file, name, proto);
|
||||||
}
|
}
|
||||||
|
@ -128,25 +132,21 @@ public class Template extends Action {
|
||||||
}
|
}
|
||||||
// templateBody.append ("\r\nreturn null;\r\n");
|
// templateBody.append ("\r\nreturn null;\r\n");
|
||||||
|
|
||||||
|
|
||||||
functionName = name;
|
|
||||||
String fname = name+"_as_string";
|
String fname = name+"_as_string";
|
||||||
String body = templateBody.toString ();
|
String body = templateBody.toString ();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
app.typemgr.readFunction (name,
|
pfunc = parseFunction (name,
|
||||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||||
body+"\r\nreturn null;\r\n",
|
body+"\r\nreturn null;\r\n");
|
||||||
prototype.getName ());
|
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
String message = x.getMessage ();
|
String message = x.getMessage ();
|
||||||
app.typemgr.generateErrorFeedback (name, message, prototype.getName ());
|
app.typemgr.generateErrorFeedback (name, message, prototype.getName ());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
app.typemgr.readFunction (fname,
|
psfunc = parseFunction (fname,
|
||||||
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
"arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10",
|
||||||
"res.pushStringBuffer(); "+body+"\r\nreturn res.popStringBuffer();\r\n",
|
"res.pushStringBuffer(); "+body+"\r\nreturn res.popStringBuffer();\r\n");
|
||||||
prototype.getName ());
|
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
String message = x.getMessage ();
|
String message = x.getMessage ();
|
||||||
app.typemgr.generateErrorFeedback (fname, message, prototype.getName ());
|
app.typemgr.generateErrorFeedback (fname, message, prototype.getName ());
|
||||||
|
@ -154,6 +154,12 @@ public class Template extends Action {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateRequestEvaluator (RequestEvaluator reval) throws EcmaScriptException {
|
||||||
|
if (pfunc != null)
|
||||||
|
pfunc.updateRequestEvaluator (reval);
|
||||||
|
if (psfunc != null)
|
||||||
|
psfunc.updateRequestEvaluator (reval);
|
||||||
|
}
|
||||||
|
|
||||||
class Part {
|
class Part {
|
||||||
|
|
||||||
|
|
|
@ -151,34 +151,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
public void registerPrototype (String name, File dir, Prototype proto) {
|
public void registerPrototype (String name, File dir, Prototype proto) {
|
||||||
// IServer.getLogger().log ("registering prototype "+name);
|
// IServer.getLogger().log ("registering prototype "+name);
|
||||||
|
|
||||||
int size = app.allThreads.size ();
|
|
||||||
for (int i=0; i<size; i++) {
|
|
||||||
RequestEvaluator reval = (RequestEvaluator) app.allThreads.elementAt (i);
|
|
||||||
ObjectPrototype op = null;
|
|
||||||
if ("user".equalsIgnoreCase (name))
|
|
||||||
op = reval.esUserPrototype;
|
|
||||||
else if ("global".equalsIgnoreCase (name))
|
|
||||||
op = reval.global;
|
|
||||||
else if ("hopobject".equalsIgnoreCase (name))
|
|
||||||
op = reval.esNodePrototype;
|
|
||||||
else {
|
|
||||||
op = new ObjectPrototype (reval.esNodePrototype, reval.evaluator);
|
|
||||||
try {
|
|
||||||
op.putProperty ("prototypename", new ESString (name), "prototypename".hashCode ());
|
|
||||||
} catch (EcmaScriptException ignore) {}
|
|
||||||
}
|
|
||||||
reval.putPrototype (name, op);
|
|
||||||
|
|
||||||
// Register a constructor for all types except global.
|
|
||||||
// This will first create a node and then call the actual (scripted) constructor on it.
|
|
||||||
if (!"global".equalsIgnoreCase (name)) {
|
|
||||||
try {
|
|
||||||
FunctionPrototype fp = (FunctionPrototype) reval.evaluator.getFunctionPrototype();
|
|
||||||
reval.global.putHiddenProperty (name, new NodeConstructor (name, fp, reval));
|
|
||||||
} catch (EcmaScriptException ignore) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// show the type checker thread that there has been type activity
|
// show the type checker thread that there has been type activity
|
||||||
idleSeconds = 0;
|
idleSeconds = 0;
|
||||||
|
|
||||||
|
@ -202,7 +174,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
ntemp.put (tmpname, t);
|
ntemp.put (tmpname, t);
|
||||||
} catch (Throwable x) {
|
} catch (Throwable x) {
|
||||||
IServer.getLogger().log ("Error creating prototype: "+x);
|
IServer.getLogger().log ("Error creating prototype: "+x);
|
||||||
// broadcaster.broadcast ("Error creating prototype "+list[i]+":<br>"+x+"<br><hr>");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (list[i].endsWith (app.scriptExtension) && tmpfile.length () > 0) {
|
} else if (list[i].endsWith (app.scriptExtension) && tmpfile.length () > 0) {
|
||||||
|
@ -211,7 +182,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
nfunc.put (tmpname, ff);
|
nfunc.put (tmpname, ff);
|
||||||
} catch (Throwable x) {
|
} catch (Throwable x) {
|
||||||
IServer.getLogger().log ("Error creating prototype: "+x);
|
IServer.getLogger().log ("Error creating prototype: "+x);
|
||||||
// broadcaster.broadcast ("Error creating prototype "+list[i]+":<br>"+x+"<br><hr>");
|
|
||||||
}
|
}
|
||||||
} else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
|
} else if (list[i].endsWith (app.actionExtension) && tmpfile.length () > 0) {
|
||||||
try {
|
try {
|
||||||
|
@ -219,7 +189,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
nact.put (tmpname, af);
|
nact.put (tmpname, af);
|
||||||
} catch (Throwable x) {
|
} catch (Throwable x) {
|
||||||
IServer.getLogger().log ("Error creating prototype: "+x);
|
IServer.getLogger().log ("Error creating prototype: "+x);
|
||||||
// broadcaster.broadcast ("Error creating prototype "+list[i]+":<br>"+x+"<br><hr>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +226,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
}
|
}
|
||||||
} catch (Throwable x) {
|
} catch (Throwable x) {
|
||||||
IServer.getLogger().log ("Error updating prototype: "+x);
|
IServer.getLogger().log ("Error updating prototype: "+x);
|
||||||
// broadcaster.broadcast ("Error updating prototype "+list[i]+":<br>"+x+"<br><hr>");
|
|
||||||
}
|
}
|
||||||
ntemp.put (tmpname, t);
|
ntemp.put (tmpname, t);
|
||||||
|
|
||||||
|
@ -273,7 +241,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
}
|
}
|
||||||
} catch (Throwable x) {
|
} catch (Throwable x) {
|
||||||
IServer.getLogger().log ("Error updating prototype: "+x);
|
IServer.getLogger().log ("Error updating prototype: "+x);
|
||||||
// broadcaster.broadcast ("Error updating prototype "+list[i]+":<br>"+x+"<br><hr>");
|
|
||||||
}
|
}
|
||||||
nfunc.put (tmpname, ff);
|
nfunc.put (tmpname, ff);
|
||||||
|
|
||||||
|
@ -289,7 +256,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
}
|
}
|
||||||
} catch (Throwable x) {
|
} catch (Throwable x) {
|
||||||
IServer.getLogger().log ("Error updating prototype: "+x);
|
IServer.getLogger().log ("Error updating prototype: "+x);
|
||||||
// broadcaster.broadcast ("Error updating prototype "+list[i]+":<br>"+x+"<br><hr>");
|
|
||||||
}
|
}
|
||||||
nact.put (tmpname, af);
|
nact.put (tmpname, af);
|
||||||
|
|
||||||
|
@ -309,100 +275,6 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
proto.actions = nact;
|
proto.actions = nact;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void readFunctionFile (File f, String protoname) {
|
|
||||||
|
|
||||||
EvaluationSource es = new FileEvaluationSource(f.getPath(), null);
|
|
||||||
FileReader fr = null;
|
|
||||||
|
|
||||||
int size = app.allThreads.size ();
|
|
||||||
for (int i=0; i<size; i++) {
|
|
||||||
RequestEvaluator reval = (RequestEvaluator) app.allThreads.elementAt (i);
|
|
||||||
|
|
||||||
try {
|
|
||||||
fr = new FileReader(f);
|
|
||||||
ObjectPrototype op = reval.getPrototype (protoname);
|
|
||||||
reval.evaluator.evaluate(fr, op, es, false);
|
|
||||||
} catch (IOException e) {
|
|
||||||
IServer.getLogger().log ("*** Error reading function file "+f+": "+e);
|
|
||||||
} catch (EcmaScriptException e) {
|
|
||||||
IServer.getLogger().log ("*** Error reading function file "+f+": "+e);
|
|
||||||
} finally {
|
|
||||||
if (fr!=null) {
|
|
||||||
try {
|
|
||||||
fr.close();
|
|
||||||
} catch (IOException ignore) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void readFunction (String funcname, String params, String body, String protoname)
|
|
||||||
throws EcmaScriptException {
|
|
||||||
|
|
||||||
// ESObject fp = app.eval.evaluator.getFunctionPrototype();
|
|
||||||
ConstructedFunctionObject function = null;
|
|
||||||
ASTFormalParameterList fpl = null;
|
|
||||||
ASTStatementList sl = null;
|
|
||||||
|
|
||||||
if (body == null || "".equals (body.trim()))
|
|
||||||
body = ";\r\n";
|
|
||||||
else
|
|
||||||
body = body + "\r\n";
|
|
||||||
if (params == null) params = "";
|
|
||||||
else params = params.trim ();
|
|
||||||
|
|
||||||
String fullFunctionText = "function "+funcname+" (" + params + ") {\n" + body + "\n}";
|
|
||||||
|
|
||||||
EcmaScript parser;
|
|
||||||
StringReader is;
|
|
||||||
|
|
||||||
// Special case for empty parameters
|
|
||||||
if (params.length()==0) {
|
|
||||||
fpl = new ASTFormalParameterList(JJTFORMALPARAMETERLIST);
|
|
||||||
} else {
|
|
||||||
is = new java.io.StringReader(params);
|
|
||||||
parser = new EcmaScript(is);
|
|
||||||
try {
|
|
||||||
fpl = (ASTFormalParameterList) parser.FormalParameterList();
|
|
||||||
is.close();
|
|
||||||
} catch (ParseException x) {
|
|
||||||
throw new EcmaScriptParseException (x, new StringEvaluationSource(fullFunctionText, null));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// this is very very very strange: without the toString, lots of obscure exceptions
|
|
||||||
// deep inside the parser...
|
|
||||||
is = new java.io.StringReader(body.toString ());
|
|
||||||
try {
|
|
||||||
parser = new EcmaScript (is);
|
|
||||||
sl = (ASTStatementList) parser.StatementList();
|
|
||||||
is.close();
|
|
||||||
} catch (ParseException x) {
|
|
||||||
x.printStackTrace ();
|
|
||||||
throw new EcmaScriptParseException (x, new StringEvaluationSource(fullFunctionText, null));
|
|
||||||
} catch (Exception x) {
|
|
||||||
x.printStackTrace ();
|
|
||||||
throw new RuntimeException (x.getMessage ());
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionEvaluationSource fes = new FunctionEvaluationSource (
|
|
||||||
new StringEvaluationSource(fullFunctionText,null), funcname);
|
|
||||||
|
|
||||||
DbMapping dbmap = null;
|
|
||||||
|
|
||||||
int size = app.allThreads.size ();
|
|
||||||
for (int i=0; i<size; i++) {
|
|
||||||
RequestEvaluator reval = (RequestEvaluator) app.allThreads.elementAt (i);
|
|
||||||
|
|
||||||
ObjectPrototype op = reval.getPrototype (protoname);
|
|
||||||
|
|
||||||
EcmaScriptVariableVisitor vdvisitor = reval.evaluator.getVarDeclarationVisitor();
|
|
||||||
Vector vnames = vdvisitor.processVariableDeclarations(sl, fes);
|
|
||||||
|
|
||||||
FunctionPrototype fp = ConstructedFunctionObject.makeNewConstructedFunction(reval.evaluator, funcname, fes, fullFunctionText, fpl.getArguments(), vnames, sl);
|
|
||||||
op.putHiddenProperty (funcname, fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void generateErrorFeedback (String funcname, String message, String protoname)
|
protected void generateErrorFeedback (String funcname, String message, String protoname)
|
||||||
|
@ -413,6 +285,7 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
RequestEvaluator reval = (RequestEvaluator) app.allThreads.elementAt (i);
|
RequestEvaluator reval = (RequestEvaluator) app.allThreads.elementAt (i);
|
||||||
|
|
||||||
ObjectPrototype op = reval.getPrototype (protoname);
|
ObjectPrototype op = reval.getPrototype (protoname);
|
||||||
|
if (op == null) return;
|
||||||
|
|
||||||
FunctionPrototype fp = (FunctionPrototype) reval.evaluator.getFunctionPrototype ();
|
FunctionPrototype fp = (FunctionPrototype) reval.evaluator.getFunctionPrototype ();
|
||||||
FunctionPrototype func = new ThrowException (funcname, reval.evaluator, fp, message);
|
FunctionPrototype func = new ThrowException (funcname, reval.evaluator, fp, message);
|
||||||
|
@ -435,6 +308,38 @@ public class TypeManager implements Runnable, EcmaScriptTreeConstants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initRequestEvaluator (RequestEvaluator reval) {
|
||||||
|
for (Enumeration en = prototypes.elements(); en.hasMoreElements(); ) {
|
||||||
|
Prototype p = (Prototype) en.nextElement ();
|
||||||
|
String name = p.getName ();
|
||||||
|
ObjectPrototype op = null;
|
||||||
|
if ("user".equalsIgnoreCase (name))
|
||||||
|
op = reval.esUserPrototype;
|
||||||
|
else if ("global".equalsIgnoreCase (name))
|
||||||
|
op = reval.global;
|
||||||
|
else if ("hopobject".equalsIgnoreCase (name))
|
||||||
|
op = reval.esNodePrototype;
|
||||||
|
else {
|
||||||
|
op = new ObjectPrototype (reval.esNodePrototype, reval.evaluator);
|
||||||
|
try {
|
||||||
|
op.putProperty ("prototypename", new ESString (name), "prototypename".hashCode ());
|
||||||
|
} catch (EcmaScriptException ignore) {}
|
||||||
|
}
|
||||||
|
reval.putPrototype (name, op);
|
||||||
|
|
||||||
|
// Register a constructor for all types except global.
|
||||||
|
// This will first create a node and then call the actual (scripted) constructor on it.
|
||||||
|
if (!"global".equalsIgnoreCase (name)) {
|
||||||
|
try {
|
||||||
|
FunctionPrototype fp = (FunctionPrototype) reval.evaluator.getFunctionPrototype();
|
||||||
|
reval.global.putHiddenProperty (name, new NodeConstructor (name, fp, reval));
|
||||||
|
} catch (EcmaScriptException ignore) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.initRequestEvaluator (reval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ public class Transactor extends Thread {
|
||||||
// The thread is told to stop by setting the thread flag in the EcmaScript
|
// The thread is told to stop by setting the thread flag in the EcmaScript
|
||||||
// evaluator, so we can hope that it stops without doing anything else.
|
// evaluator, so we can hope that it stops without doing anything else.
|
||||||
try {
|
try {
|
||||||
join (1000);
|
join (500);
|
||||||
} catch (InterruptedException ir) {
|
} catch (InterruptedException ir) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
|
@ -222,6 +222,7 @@ public class Transactor extends Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup () {
|
public void cleanup () {
|
||||||
|
// IServer.getLogger().log("Cleaning up Transactor thread");
|
||||||
if (sqlCon != null) {
|
if (sqlCon != null) {
|
||||||
for (Iterator i=sqlCon.values().iterator(); i.hasNext(); ) {
|
for (Iterator i=sqlCon.values().iterator(); i.hasNext(); ) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -101,4 +101,4 @@ public class Benchmark implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,10 +76,6 @@ public class XmlRpcClient implements XmlRpcHandler {
|
||||||
return retval;
|
return retval;
|
||||||
} finally {
|
} finally {
|
||||||
worker.reset ();
|
worker.reset ();
|
||||||
if (workers < 20 && !worker.fault)
|
|
||||||
pool.push (worker);
|
|
||||||
else
|
|
||||||
workers -= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +149,8 @@ public class XmlRpcClient implements XmlRpcHandler {
|
||||||
} catch (Exception x) {
|
} catch (Exception x) {
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
callback.handleError (x, url, method);
|
callback.handleError (x, url, method);
|
||||||
|
} finally {
|
||||||
|
reset ();
|
||||||
}
|
}
|
||||||
System.err.println ("GOT: "+result);
|
System.err.println ("GOT: "+result);
|
||||||
}
|
}
|
||||||
|
@ -255,6 +253,11 @@ public class XmlRpcClient implements XmlRpcHandler {
|
||||||
result = null;
|
result = null;
|
||||||
params = null;
|
params = null;
|
||||||
callback = null;
|
callback = null;
|
||||||
|
if (workers < 20 && !fault)
|
||||||
|
pool.push (this);
|
||||||
|
else
|
||||||
|
workers -= 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of inner class Worker
|
} // end of inner class Worker
|
||||||
|
@ -274,7 +277,7 @@ public class XmlRpcClient implements XmlRpcHandler {
|
||||||
} catch (NumberFormatException nfx) {
|
} catch (NumberFormatException nfx) {
|
||||||
v.addElement (args[i]);
|
v.addElement (args[i]);
|
||||||
}
|
}
|
||||||
XmlRpcClient client = new XmlRpcClient (url);
|
XmlRpcClient client = new XmlRpcClientLite (url);
|
||||||
try {
|
try {
|
||||||
/* System.err.println (*/client.executeAsync (method, v, null);
|
/* System.err.println (*/client.executeAsync (method, v, null);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
|
|
@ -75,19 +75,52 @@ public class XmlRpcClientLite extends XmlRpcClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Worker extends XmlRpc {
|
class Worker extends XmlRpc implements Runnable {
|
||||||
|
|
||||||
boolean fault;
|
boolean fault;
|
||||||
Object result = null;
|
Object result = null;
|
||||||
HttpClient client = null;
|
HttpClient client = null;
|
||||||
StringBuffer strbuf;
|
StringBuffer strbuf;
|
||||||
|
String method;
|
||||||
|
Vector params;
|
||||||
|
AsyncCallback callback = null;
|
||||||
|
|
||||||
public Worker () {
|
public Worker () {
|
||||||
super ();
|
super ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object execute (String method, Vector params) throws XmlRpcException, IOException {
|
public Object execute (String method, Vector params) throws XmlRpcException, IOException {
|
||||||
|
this.method = method;
|
||||||
|
this.params = params;
|
||||||
|
return executeCall ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void executeAsync (String method, Vector params, AsyncCallback callback) {
|
||||||
|
this.method = method;
|
||||||
|
this.params = params;
|
||||||
|
this.callback = callback;
|
||||||
|
Thread t = new Thread (this);
|
||||||
|
t.start ();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run () {
|
||||||
|
Object res = null;
|
||||||
|
try {
|
||||||
|
res = executeCall ();
|
||||||
|
// notify callback object
|
||||||
|
if (callback != null)
|
||||||
|
callback.handleResult (res, url, method);
|
||||||
|
} catch (Exception x) {
|
||||||
|
if (callback != null)
|
||||||
|
callback.handleError (x, url, method);
|
||||||
|
} finally {
|
||||||
|
reset ();
|
||||||
|
}
|
||||||
|
System.err.println ("GOT: "+result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object executeCall () throws XmlRpcException, IOException {
|
||||||
long now = System.currentTimeMillis ();
|
long now = System.currentTimeMillis ();
|
||||||
fault = false;
|
fault = false;
|
||||||
try {
|
try {
|
||||||
|
@ -196,6 +229,20 @@ public class XmlRpcClientLite extends XmlRpcClient {
|
||||||
super.startElement (name, atts);
|
super.startElement (name, atts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release possibly big per-call object references to allow them to be garbage collected
|
||||||
|
*/
|
||||||
|
public void reset () {
|
||||||
|
result = null;
|
||||||
|
params = null;
|
||||||
|
callback = null;
|
||||||
|
if (workers < 20 && !fault)
|
||||||
|
pool.push (this);
|
||||||
|
else
|
||||||
|
workers -= 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // end of class Worker
|
} // end of class Worker
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue