more work to solve "shringking prototypes" problem
in FunctionFile
This commit is contained in:
parent
20e8bb8987
commit
27d07e599c
2 changed files with 85 additions and 29 deletions
|
@ -24,9 +24,11 @@ public class FunctionFile implements Updatable {
|
|||
Application app;
|
||||
File file;
|
||||
long lastmod;
|
||||
|
||||
// a set of funcion names defined by this file. We keep this to be able to
|
||||
// remove them once the file should get removed
|
||||
HashSet functionNames;
|
||||
HashSet declaredProps;
|
||||
long declaredPropsTimestamp;
|
||||
|
||||
public FunctionFile (File file, String name, Prototype proto) {
|
||||
this.prototype = proto;
|
||||
|
@ -54,13 +56,15 @@ public class FunctionFile implements Updatable {
|
|||
} else {
|
||||
|
||||
lastmod = file.lastModified ();
|
||||
functionNames = null;
|
||||
// app.typemgr.readFunctionFile (file, prototype.getName ());
|
||||
|
||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||
while (evals.hasNext ()) {
|
||||
try {
|
||||
|
||||
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||
updateRequestEvaluator (reval);
|
||||
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
@ -72,23 +76,40 @@ public class FunctionFile implements Updatable {
|
|||
EvaluationSource es = new FileEvaluationSource(file.getPath(), null);
|
||||
FileReader fr = null;
|
||||
|
||||
HashMap priorProps = new HashMap ();
|
||||
ObjectPrototype op = null;
|
||||
HashMap priorProps = null;
|
||||
HashSet newProps = null;
|
||||
|
||||
try {
|
||||
op = reval.getPrototype (prototype.getName());
|
||||
|
||||
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||
|
||||
// extract all properties from prototype _before_ evaluation, so we can compare afterwards
|
||||
// but only do this is declaredProps is not up to date yet
|
||||
if (declaredPropsTimestamp != lastmod) {
|
||||
priorProps = new HashMap ();
|
||||
// remember properties before evaluation, so we can tell what's new afterwards
|
||||
if (functionNames == null) try {
|
||||
try {
|
||||
for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
|
||||
String prop = (String) en.nextElement ();
|
||||
priorProps.put (prop, op.getProperty (prop, prop.hashCode()));
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
// do the update, evaluating the file
|
||||
fr = new FileReader(file);
|
||||
reval.evaluator.evaluate(fr, op, es, false);
|
||||
|
||||
// check what's new
|
||||
if (declaredPropsTimestamp != lastmod) try {
|
||||
newProps = new HashSet ();
|
||||
for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
|
||||
String prop = (String) en.nextElement ();
|
||||
if (priorProps.get (prop) == null || op.getProperty (prop, prop.hashCode()) != priorProps.get (prop))
|
||||
newProps.add (prop);
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
|
||||
} catch (IOException e) {
|
||||
app.logEvent ("Error parsing function file "+app.getName()+":"+prototype.getName()+"/"+file.getName()+": "+e);
|
||||
} catch (EcmaScriptException e) {
|
||||
|
@ -100,44 +121,64 @@ public class FunctionFile implements Updatable {
|
|||
} catch (IOException ignore) {}
|
||||
}
|
||||
|
||||
// check
|
||||
if (functionNames == null && op != null) try {
|
||||
functionNames = new HashSet ();
|
||||
for (Enumeration en=op.getAllProperties(); en.hasMoreElements(); ) {
|
||||
String prop = (String) en.nextElement ();
|
||||
if (priorProps.get (prop) == null || op.getProperty (prop, prop.hashCode()) != priorProps.get (prop))
|
||||
functionNames.add (prop);
|
||||
// now remove the props that were not refreshed, and set declared props to new collection
|
||||
if (declaredPropsTimestamp != lastmod) {
|
||||
declaredPropsTimestamp = lastmod;
|
||||
if (declaredProps != null) {
|
||||
declaredProps.removeAll (newProps);
|
||||
removeProperties (declaredProps);
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
declaredProps = newProps;
|
||||
// System.err.println ("DECLAREDPROPS = "+declaredProps);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void remove () {
|
||||
prototype.functions.remove (name);
|
||||
prototype.updatables.remove (file.getName());
|
||||
|
||||
// if we did not add anything to any evaluator, we're done
|
||||
if (functionNames == null)
|
||||
if (declaredProps == null || declaredProps.size() == 0)
|
||||
return;
|
||||
|
||||
removeProperties (declaredProps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the properties in the HashMap iff they're still the same as declared by this file.
|
||||
* This method is called by remove() with the latest props, and by update with the prior props
|
||||
* after the file has been reevaluated.
|
||||
*/
|
||||
void removeProperties (HashSet props) {
|
||||
// first loop through other function files in this prototype to make a set of properties
|
||||
// owned by other files.
|
||||
HashSet otherFiles = new HashSet ();
|
||||
for (Iterator it=prototype.functions.values ().iterator (); it.hasNext (); ) {
|
||||
FunctionFile other = (FunctionFile) it.next ();
|
||||
if (other != this && other.declaredProps != null)
|
||||
otherFiles.addAll (other.declaredProps);
|
||||
}
|
||||
|
||||
Iterator evals = app.typemgr.getRegisteredRequestEvaluators ();
|
||||
while (evals.hasNext ()) {
|
||||
try {
|
||||
RequestEvaluator reval = (RequestEvaluator) evals.next ();
|
||||
ObjectPrototype op = reval.getPrototype (prototype.getName());
|
||||
for (Iterator it=functionNames.iterator(); it.hasNext(); ) {
|
||||
for (Iterator it = props.iterator (); it.hasNext (); ) {
|
||||
String fname = (String) it.next ();
|
||||
ESValue esv = op.getProperty (fname, fname.hashCode());
|
||||
if (esv instanceof ConstructedFunctionObject) {
|
||||
// check if this property has been declared by some other function file in the meantime
|
||||
if (otherFiles.contains (fname))
|
||||
continue;
|
||||
op.deleteProperty (fname, fname.hashCode());
|
||||
}
|
||||
// System.err.println ("REMOVING PROP: "+fname);
|
||||
}
|
||||
} catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,14 @@ public class TypeManager implements Runnable {
|
|||
// } catch (IOException ignore) {}
|
||||
// }
|
||||
|
||||
static HashSet standardTypes;
|
||||
static {
|
||||
standardTypes = new HashSet ();
|
||||
standardTypes.add ("user");
|
||||
standardTypes.add ("global");
|
||||
standardTypes.add ("root");
|
||||
standardTypes.add ("hopobject");
|
||||
}
|
||||
|
||||
public TypeManager (Application app) {
|
||||
this.app = app;
|
||||
|
@ -87,6 +95,13 @@ public class TypeManager implements Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
/* for (Iterator it=prototypes.values ().iterator (); it.hasNext (); ) {
|
||||
Prototype proto = (Prototype) it.next ();
|
||||
if (!proto.getCodeDir ().exists ()) {
|
||||
app.logEvent ("TypeManager: Can't remove prototype from running application. Restart for changes to take effect.");
|
||||
}
|
||||
} */
|
||||
|
||||
if (rewire) {
|
||||
// there have been changes @ DbMappings
|
||||
app.rewireDbMappings ();
|
||||
|
@ -134,7 +149,7 @@ public class TypeManager implements Runnable {
|
|||
// for each idle minute, add 300 ms to sleeptime until 5 secs are reached.
|
||||
// (10 secs are reached after 30 minutes of idle state)
|
||||
// the above is all false.
|
||||
long sleeptime = 1500 + Math.min (idleSeconds*30, 3500);
|
||||
long sleeptime = 1000 + Math.min (idleSeconds*30, 4000);
|
||||
typechecker.sleep (sleeptime);
|
||||
} catch (InterruptedException x) {
|
||||
// app.logEvent ("Typechecker interrupted");
|
||||
|
|
Loading…
Add table
Reference in a new issue