Mercurial Hosting > luan
changeset 1230:034f2a0b3915
better gc
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 04 Apr 2018 14:54:29 -0600 |
parents | 85aa7961239a |
children | 0b75337bb91a |
files | src/luan/host/WebHandler.java |
diffstat | 1 files changed, 53 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
diff -r 85aa7961239a -r 034f2a0b3915 src/luan/host/WebHandler.java --- a/src/luan/host/WebHandler.java Mon Apr 02 02:13:02 2018 -0600 +++ b/src/luan/host/WebHandler.java Wed Apr 04 14:54:29 2018 -0600 @@ -5,6 +5,7 @@ import java.lang.ref.Reference; import java.lang.ref.SoftReference; //import java.lang.ref.WeakReference; +import java.lang.ref.ReferenceQueue; import java.util.Map; import java.util.HashMap; import org.slf4j.Logger; @@ -30,8 +31,38 @@ public class WebHandler implements Handler { private static final Logger logger = LoggerFactory.getLogger(WebHandler.class); + private static class LuanRef { + private final LuanState luan; + + private LuanRef(LuanState luan) { + this.luan = luan; + } + } + + private static final ReferenceQueue<LuanRef> queue = new ReferenceQueue<LuanRef>(); + + private static class MyReference extends SoftReference<LuanRef> { + private final LuanState luan; + + private MyReference(LuanRef lr) { + super(lr,queue); + this.luan = lr.luan; + } + } + + private static void sweep() { + while(true) { + MyReference ref = (MyReference)queue.poll(); + if( ref == null ) + return; + logger.info("sweep"); + ref.luan.close(); + } + } + + public static String allowJavaFileName = "allow_java"; // change for security - private static final Map<String,Reference<LuanState>> siteMap = new HashMap<String,Reference<LuanState>>(); + private static final Map<String,MyReference> siteMap = new HashMap<String,MyReference>(); private static String sitesDir = null; private static final String HANDLER = "WebHandler.handler"; @@ -46,7 +77,7 @@ throw new RuntimeException("already set"); if( !new File(dir).exists() ) throw new RuntimeException(); - this.sitesDir = dir; + sitesDir = dir; } public Response handle(Request request) { @@ -54,40 +85,45 @@ int i = host.indexOf(':'); String domain = i == -1 ? host : host.substring(0,i); // System.out.println("handle "+domain); - LuanState luan = getSite(domain); - if( luan == null ) + LuanRef lr = getSite(domain); + if( lr == null ) return null; + LuanState luan = lr.luan; Handler handler = (Handler)luan.registry().get(HANDLER); return handler.handle(request); } public static Object runLuan(String domain,String sourceText,String sourceName) throws LuanException { - LuanState luan = getSite(domain); + LuanRef lr = getSite(domain); + LuanState luan = lr.luan; LuanHandler luanHandler = (LuanHandler)luan.registry().get(LUAN_HANDLER); return luanHandler.runLuan(sourceText,sourceName); } public static Object callSite(String domain,String fnName,Object... args) throws LuanException { - LuanState luan = getSite(domain); + LuanRef lr = getSite(domain); + LuanState luan = lr.luan; LuanHandler luanHandler = (LuanHandler)luan.registry().get(LUAN_HANDLER); return luanHandler.call_rpc(fnName,args); } - private static LuanState getSite(String domain) { + private static LuanRef getSite(String domain) { synchronized(siteMap) { - Reference<LuanState> ref = siteMap.get(domain); - LuanState luan = ref==null ? null : ref.get(); - if( luan == null ) { + Reference<LuanRef> ref = siteMap.get(domain); + LuanRef lr = ref==null ? null : ref.get(); + if( lr == null ) { //if(ref!=null) logger.info("gc "+domain); if( sitesDir==null ) throw new NullPointerException("sitesDir"); File dir = new File(sitesDir,domain); if( !dir.exists() /* && !recover(dir) */ ) return null; - luan = newSite(dir.toString(),domain); - siteMap.put(domain,new SoftReference<LuanState>(luan)); + sweep(); + LuanState luan = newSite(dir.toString(),domain); + lr = new LuanRef(luan); + siteMap.put(domain,new MyReference(lr)); } - return luan; + return lr; } } /* @@ -152,9 +188,10 @@ public static void removeHandler(String domain) throws Exception { synchronized(siteMap) { - Reference<LuanState> ref = siteMap.remove(domain); - LuanState luan = ref==null ? null : ref.get(); - if( luan != null ) { + Reference<LuanRef> ref = siteMap.remove(domain); + LuanRef lr = ref==null ? null : ref.get(); + if( lr != null ) { + LuanState luan = lr.luan; LuanHandler luanHandler = (LuanHandler)luan.registry().get(LUAN_HANDLER); luanHandler.close(); }