On Tuesday 05 June 2001 23:44, you wrote: > > I have noticed with recent CVS that FProxy is slow to return pages, and > sometimes it hangs for ages without returning an error message. Now it > may be something todo with my HTL 100, combined with QueryRestarted > messages coming from somewhere. I am getting suspicious that > QueryRestarted messages may not be such a hot idea. > > Ian. Hi Ian, I found two problems. Problem 1: Coarse grained lock in MapHandler.lookup() In the current implementation every request that goes through an MSK has to acquire the lock for the synchronized static function MapHandler.lookup(). This means that concurrent requests for MSK URI's are serialized. Back when default htl's were low (15!) this wasn't a very big issue. With an htl of 100 it looks pretty bad. Problem 2-- fproxy doesn't cancel freenet requests associated with aborted http requests. This compounds problem 1. e.g. I click on an MSK site. It doesn't load so I give up and click on another site. The problem is, the second site won't even start to load until the freenet request for the mapfile used by the first site finishes. If you click on several MSK sites in succession, fproxy can stall for several minutes or longer. I fixed Problem 1 in my local tree by implementing a slightly more complicated cache strategy with finer grained locking. Diffs are attached. If no one screams I will check this change into the head branch later today. My fix makes the stalls go away. Problem 2 is ugly because of unnecessary resource use, but it doesn't affect usability once Problem 1 is fixed. I will leave Problem 2 to someone else... -- gj -- Web page inside Freenet: freenet:MSK@SSK@enI8YFo3gj8UVh-Au0HpKMftf6QQAgE/homepage//
Index: client/MapHandler.java =================================================================== RCS file: /cvsroot/freenet/Freenet/client/MapHandler.java,v retrieving revision 1.6 diff -r1.6 MapHandler.java 10,11c10,71 < private static MapFile mapfile = null; < private static String key; --- > /* > NOTES ON CACHING: > We want to cache MapFiles because they take a while to > create and are typically hit multiple times with each page > load as embedded images are requested. > > MapFile references are cached after each lookup. Different > threads can make conncurrent lookups on the same MapFile but in > the case of a race, only the newest version is cached. > > Cached entries go stale after 10 seconds and are purged > on the next lookup. > > I ([EMAIL PROTECTED]) made these changes to get > rid of an intermittent stall in fproxy ( < 20010606 ) caused > by long waits in the old synchronized MapHandler.lookup() > implementation. > */ > private static Hashtable mapFileTable = new Hashtable(); > private static final MapFile getMapFile(String mapKey, Params params) { > MapFile ret = null; > > synchronized (mapFileTable) { > // Purge out of date entries from the table. > long now = new Date().getTime(); > for (Enumeration e = mapFileTable.keys() ; e.hasMoreElements() ;) { > final String key = (String)e.nextElement(); > final MapFile entry = (MapFile)mapFileTable.get(key); > if (entry.atime + 10000 < now) { > mapFileTable.remove(key); > //System.err.println("MapHandler.getMapFile -- removed cached entry: " + key); > } > } > > // look up MapFile > ret = (MapFile)mapFileTable.get(mapKey); > } > > if (ret == null) { > // IMPORTANT: Don't hold any locks while reading > // the MSK mapfile, because it > // can take a long time. multiple minutes! > ret = new MapFile(mapKey, params); > } > > synchronized (mapFileTable) { > if (mapFileTable.get(mapKey) == null) { > mapFileTable.put(mapKey, ret); > //System.err.println("MapHandler.getMapFile -- added cached entry: " + mapKey); > } > else { > // Check the time stamp in case a newer version was cached > // by another thread. > final MapFile old = (MapFile)mapFileTable.get(mapKey); > if (old.atime < ret.atime) { > mapFileTable.put(mapKey, ret); > //System.err.println("MapHandler.getMapFile -- updated cached entry: " + mapKey); > } > } > } > return ret; > } 16c76 < public static synchronized String lookup(String uri, Params params) { --- > public static String lookup(String uri, Params params) { 21c81 < String mapkey = uri.substring(0,delim); --- > String mapKey = uri.substring(0,delim); 23,27c83 < if (mapfile == null || !key.equals(mapkey) || mapfile.atime + 10000 < new Date().getTime()) { < key = mapkey; < mapfile = new MapFile(mapkey,params); < } < return mapfile.lookup(filename); --- > return getMapFile(mapKey, params).lookup(filename); 29a86,93 > > > > > > > >