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:
hns 2001-08-29 18:03:54 +00:00
parent d6e09cae8c
commit 6353177656

View file

@ -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 ()) {