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
--- 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();
 			}