Optimized the check for updates.
Typemanager is now run in an experimental mode without its own thread and being called before a request is evaluated.
This commit is contained in:
parent
d6e09cae8c
commit
6353177656
1 changed files with 64 additions and 50 deletions
|
@ -5,6 +5,7 @@ package helma.framework.core;
|
||||||
|
|
||||||
import helma.objectmodel.*;
|
import helma.objectmodel.*;
|
||||||
import helma.objectmodel.db.DbMapping;
|
import helma.objectmodel.db.DbMapping;
|
||||||
|
import helma.scripting.*;
|
||||||
import helma.util.*;
|
import helma.util.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -21,6 +22,7 @@ public class TypeManager implements Runnable {
|
||||||
File appDir;
|
File appDir;
|
||||||
HashMap prototypes;
|
HashMap prototypes;
|
||||||
HashMap zipfiles;
|
HashMap zipfiles;
|
||||||
|
long lastCheck = 0;
|
||||||
long idleSeconds = 120; // if idle for longer than 5 minutes, slow down
|
long idleSeconds = 120; // if idle for longer than 5 minutes, slow down
|
||||||
boolean rewire;
|
boolean rewire;
|
||||||
|
|
||||||
|
@ -30,13 +32,6 @@ public class TypeManager implements Runnable {
|
||||||
|
|
||||||
Thread typechecker;
|
Thread typechecker;
|
||||||
|
|
||||||
// The http broadcaster for pushing out parser output
|
|
||||||
// static WebBroadcaster broadcaster;
|
|
||||||
// static {
|
|
||||||
// try {
|
|
||||||
// broadcaster = new WebBroadcaster (9999);
|
|
||||||
// } catch (IOException ignore) {}
|
|
||||||
// }
|
|
||||||
|
|
||||||
static HashSet standardTypes;
|
static HashSet standardTypes;
|
||||||
static {
|
static {
|
||||||
|
@ -64,34 +59,45 @@ public class TypeManager implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void check () {
|
public void createPrototypes () {
|
||||||
|
check (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public synchronized void checkPrototypes () {
|
||||||
|
if (System.currentTimeMillis () - lastCheck < 500l)
|
||||||
|
return;
|
||||||
|
lastCheck = System.currentTimeMillis ();
|
||||||
|
check (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void check (boolean update) {
|
||||||
// long now = System.currentTimeMillis ();
|
// long now = System.currentTimeMillis ();
|
||||||
// System.out.print ("checking "+Thread.currentThread ());
|
// System.out.print ("checking "+Thread.currentThread ());
|
||||||
String[] list = appDir.list ();
|
// long total = System.currentTimeMillis();
|
||||||
|
File[] list = appDir.listFiles ();
|
||||||
if (list == null)
|
if (list == null)
|
||||||
throw new RuntimeException ("Can't read app directory "+appDir+" - check permissions");
|
throw new RuntimeException ("Can't read app directory "+appDir+" - check permissions");
|
||||||
for (int i=0; i<list.length; i++) {
|
for (int i=0; i<list.length; i++) {
|
||||||
File fileOrDir = new File (appDir, list[i]);
|
String filename = list[i].getName ();
|
||||||
// cut out ".." and other directories that contain "."
|
Prototype proto = getPrototype (filename);
|
||||||
if (isValidTypeName (list[i]) && fileOrDir.isDirectory ()) {
|
if (proto != null) {
|
||||||
Prototype proto = getPrototype (list[i]);
|
// check if existing prototype needs update
|
||||||
if (proto != null) {
|
// app.logEvent (protoDir.lastModified ());
|
||||||
// check if existing prototype needs update
|
updatePrototype (filename, list[i], proto);
|
||||||
// app.logEvent (protoDir.lastModified ());
|
} else if (list[i].isDirectory () && isValidTypeName (filename)) {
|
||||||
updatePrototype (list[i], fileOrDir, proto);
|
// leave out ".." and other directories that contain "."
|
||||||
} else {
|
// create new prototype
|
||||||
// create new prototype
|
proto = new Prototype (filename, app);
|
||||||
proto = new Prototype (list[i], app);
|
registerPrototype (filename, list[i], proto, update);
|
||||||
registerPrototype (list[i], fileOrDir, proto);
|
prototypes.put (filename, proto);
|
||||||
prototypes.put (list[i], proto);
|
// give logger thread a chance to tell what's going on
|
||||||
// give logger thread a chance to tell what's going on
|
// Thread.yield();
|
||||||
Thread.yield();
|
} else if (filename.toLowerCase().endsWith (".zip") && !list[i].isDirectory ()) {
|
||||||
}
|
ZippedAppFile zipped = (ZippedAppFile) zipfiles.get (filename);
|
||||||
} else if (list[i].toLowerCase().endsWith (".zip") && !fileOrDir.isDirectory ()) {
|
|
||||||
ZippedAppFile zipped = (ZippedAppFile) zipfiles.get (list[i]);
|
|
||||||
if (zipped == null) {
|
if (zipped == null) {
|
||||||
zipped = new ZippedAppFile (fileOrDir, app);
|
zipped = new ZippedAppFile (list[i], app);
|
||||||
zipfiles.put (list[i], zipped);
|
zipfiles.put (filename, zipped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +109,7 @@ public class TypeManager implements Runnable {
|
||||||
zipped.update ();
|
zipped.update ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// System.err.println ("TOTAL: "+(System.currentTimeMillis () - total));
|
||||||
if (rewire) {
|
if (rewire) {
|
||||||
// there have been changes @ DbMappings
|
// there have been changes @ DbMappings
|
||||||
app.rewireDbMappings ();
|
app.rewireDbMappings ();
|
||||||
|
@ -153,7 +159,7 @@ public class TypeManager implements Runnable {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
check ();
|
checkPrototypes ();
|
||||||
} catch (Exception ignore) {}
|
} catch (Exception ignore) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +193,7 @@ public class TypeManager implements Runnable {
|
||||||
/**
|
/**
|
||||||
* Create a prototype from a directory containing scripts and other stuff
|
* Create a prototype from a directory containing scripts and other stuff
|
||||||
*/
|
*/
|
||||||
public void registerPrototype (String name, File dir, Prototype proto) {
|
public void registerPrototype (String name, File dir, Prototype proto, boolean update) {
|
||||||
// app.logEvent ("registering prototype "+name);
|
// app.logEvent ("registering prototype "+name);
|
||||||
|
|
||||||
// show the type checker thread that there has been type activity
|
// show the type checker thread that there has been type activity
|
||||||
|
@ -200,6 +206,7 @@ public class TypeManager implements Runnable {
|
||||||
HashMap nskins = new HashMap ();
|
HashMap nskins = new HashMap ();
|
||||||
HashMap updatables = new HashMap (list.length);
|
HashMap updatables = new HashMap (list.length);
|
||||||
|
|
||||||
|
if (update) {
|
||||||
for (int i=0; i<list.length; i++) {
|
for (int i=0; i<list.length; i++) {
|
||||||
File tmpfile = new File (dir, list[i]);
|
File tmpfile = new File (dir, list[i]);
|
||||||
int dot = list[i].indexOf (".");
|
int dot = list[i].indexOf (".");
|
||||||
|
@ -245,6 +252,7 @@ public class TypeManager implements Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create and register type properties file
|
// Create and register type properties file
|
||||||
File propfile = new File (dir, "type.properties");
|
File propfile = new File (dir, "type.properties");
|
||||||
|
@ -273,35 +281,41 @@ public class TypeManager implements Runnable {
|
||||||
* Update a prototype based on the directory which defines it.
|
* Update a prototype based on the directory which defines it.
|
||||||
*/
|
*/
|
||||||
public void updatePrototype (String name, File dir, Prototype proto) {
|
public void updatePrototype (String name, File dir, Prototype proto) {
|
||||||
// app.logEvent ("updating prototype "+name);
|
|
||||||
|
|
||||||
boolean needsUpdate = false;
|
boolean needsUpdate = false;
|
||||||
HashSet updatables = new HashSet ();
|
HashSet updatables = new HashSet ();
|
||||||
|
|
||||||
// our plan is to do as little as possible, so first check if anything has changed at all...
|
// our plan is to do as little as possible, so first check if anything has changed at all...
|
||||||
for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) {
|
for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) {
|
||||||
Updatable upd = (Updatable) i.next();
|
Updatable upd = (Updatable) i.next();
|
||||||
if (upd.needsUpdate ()) {
|
if (upd.needsUpdate ()) {
|
||||||
needsUpdate = true;
|
needsUpdate = true;
|
||||||
updatables.add (upd);
|
updatables.add (upd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String list[] = dir.list();
|
String[] list = new String[0];
|
||||||
for (int i=0; i<list.length; i++) {
|
// check if file have been created since last update
|
||||||
String fn = list[i];
|
if (proto.lastUpdate < dir.lastModified ()) {
|
||||||
if (!proto.updatables.containsKey (fn)) {
|
list = dir.list();
|
||||||
if (fn.endsWith (app.templateExtension) || fn.endsWith (app.scriptExtension) ||
|
for (int i=0; i<list.length; i++) {
|
||||||
fn.endsWith (app.actionExtension) || fn.endsWith (app.skinExtension) || "type.properties".equalsIgnoreCase (fn)) {
|
String fn = list[i];
|
||||||
needsUpdate = true;
|
if (!proto.updatables.containsKey (fn)) {
|
||||||
updatables.add ("[new:"+proto.getName()+"/"+fn+"]");
|
if (fn.endsWith (app.templateExtension) || fn.endsWith (app.scriptExtension) ||
|
||||||
}
|
fn.endsWith (app.actionExtension) || fn.endsWith (app.skinExtension) ||
|
||||||
}
|
"type.properties".equalsIgnoreCase (fn)) {
|
||||||
|
needsUpdate = true;
|
||||||
|
// updatables.add ("[new:"+proto.getName()+"/"+fn+"]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needsUpdate)
|
if (!needsUpdate)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
proto.lastUpdate = System.currentTimeMillis ();
|
||||||
|
|
||||||
// let the thread know we had to do something.
|
// let the thread know we had to do something.
|
||||||
idleSeconds = 0;
|
idleSeconds = 0;
|
||||||
app.logEvent ("TypeManager: Updating prototypes for "+app.getName()+": "+updatables);
|
app.logEvent ("TypeManager: Updating prototypes for "+app.getName()+": "+updatables);
|
||||||
|
@ -357,7 +371,7 @@ public class TypeManager implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// next go through existing updatables
|
// next go through existing updatables
|
||||||
for (Iterator i = proto.updatables.values().iterator(); i.hasNext(); ) {
|
for (Iterator i = updatables.iterator(); i.hasNext(); ) {
|
||||||
Updatable upd = (Updatable) i.next();
|
Updatable upd = (Updatable) i.next();
|
||||||
|
|
||||||
if (upd.needsUpdate ()) {
|
if (upd.needsUpdate ()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue