changeset 1202:d3a3ca116e42

gc site instances
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 05 Mar 2018 19:30:51 -0700
parents 7f4a12fb7716
children 7e6d132904fd
files src/luan/LuanState.java src/luan/host/WebHandler.java src/luan/modules/ThreadLuan.java
diffstat 3 files changed, 43 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/LuanState.java	Sun Mar 04 17:07:48 2018 -0700
+++ b/src/luan/LuanState.java	Mon Mar 05 19:30:51 2018 -0700
@@ -55,6 +55,10 @@
 		onClose.clear();
 	}
 
+	protected void finalize() throws Throwable {
+		close();
+	}
+
 	public final Object eval(String cmd,Object... args) throws LuanException {
 		return Luan.load(cmd,"eval").call(this,args);
 	}
--- a/src/luan/host/WebHandler.java	Sun Mar 04 17:07:48 2018 -0700
+++ b/src/luan/host/WebHandler.java	Mon Mar 05 19:30:51 2018 -0700
@@ -2,6 +2,9 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+//import java.lang.ref.WeakReference;
 import java.util.Map;
 import java.util.HashMap;
 import org.slf4j.Logger;
@@ -27,19 +30,12 @@
 public class WebHandler implements Handler {
 	private static final Logger logger = LoggerFactory.getLogger(WebHandler.class);
 
-	private static class Site {
-		final Handler handler;
-		final LuanHandler luanHandler;
+	public static String allowJavaFileName = "allow_java";  // change for security
+	private static final Map<String,Reference<LuanState>> siteMap = new HashMap<String,Reference<LuanState>>();
+	private static String sitesDir = null;
 
-		Site(Handler handler,LuanHandler luanHandler) {
-			this.handler = handler;
-			this.luanHandler = luanHandler;
-		}
-	}
-
-	public static String allowJavaFileName = "allow_java";  // change for security
-	private static final Map<String,Site> siteMap = new HashMap<String,Site>();
-	private static String sitesDir = null;
+	private static final String HANDLER = "WebHandler.handler";
+	private static final String LUAN_HANDLER = "WebHandler.luanHandler";
 
 	public static boolean isServing() {
 		return sitesDir != null;
@@ -58,31 +54,40 @@
 		int i = host.indexOf(':');
 		String domain = i == -1 ? host : host.substring(0,i);
 //		System.out.println("handle "+domain);
-		Site site = getSite(domain);
-		return site==null ? null : site.handler.handle(request);
+		LuanState luan = getSite(domain);
+		if( luan == null )
+			return null;
+		Handler handler = (Handler)luan.registry().get(HANDLER);
+		return handler.handle(request);
 	}
 
 	public static Object runLuan(String domain,String sourceText,String sourceName) throws LuanException {
-		return getSite(domain).luanHandler.runLuan(sourceText,sourceName);
+		LuanState luan = getSite(domain);
+		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 {
-		return getSite(domain).luanHandler.call_rpc(fnName,args);
+		LuanState luan = getSite(domain);
+		LuanHandler luanHandler = (LuanHandler)luan.registry().get(LUAN_HANDLER);
+		return luanHandler.call_rpc(fnName,args);
 	}
 
-	private static Site getSite(String domain) {
+	private static LuanState getSite(String domain) {
 		synchronized(siteMap) {
-			Site site = siteMap.get(domain);
-			if( site == null ) {
+			Reference<LuanState> ref = siteMap.get(domain);
+			LuanState luan = ref==null ? null : ref.get();
+			if( luan == 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;
-				site = newSite(dir.toString(),domain);
-				siteMap.put(domain,site);
+				luan = newSite(dir.toString(),domain);
+				siteMap.put(domain,new SoftReference<LuanState>(luan));
 			}
-			return site;
+			return luan;
 		}
 	}
 /*
@@ -124,7 +129,7 @@
 		return init;
 	}
 
-	private static Site newSite(String dir,String domain) {
+	private static LuanState newSite(String dir,String domain) {
 		LuanState luan = new LuanState();
 		LuanTable init = initLuan(luan,dir,domain);
 
@@ -136,17 +141,22 @@
 		handler = new IndexHandler(handler);
 		handler = new ListHandler( handler, notFoundHandler );
 
-		String logDir = dir+"/site/private/local/logs/web";
+		String logDir = dir + "/site/private/local/logs/web";
 		new File(logDir).mkdirs();
 
-		return new Site(handler,luanHandler);
+		luan.registry().put(HANDLER,handler);
+		luan.registry().put(LUAN_HANDLER,luanHandler);
+
+		return luan;
 	}
 
 	public static void removeHandler(String domain) throws Exception {
 		synchronized(siteMap) {
-			Site site = siteMap.remove(domain);
-			if( site != null ) {
-				site.luanHandler.close();
+			Reference<LuanState> ref = siteMap.remove(domain);
+			LuanState luan = ref==null ? null : ref.get();
+			if( luan != null ) {
+				LuanHandler luanHandler = (LuanHandler)luan.registry().get(LUAN_HANDLER);
+				luanHandler.close();
 			}
 		}
 	}
--- a/src/luan/modules/ThreadLuan.java	Sun Mar 04 17:07:48 2018 -0700
+++ b/src/luan/modules/ThreadLuan.java	Mon Mar 05 19:30:51 2018 -0700
@@ -69,6 +69,7 @@
 		final Closeable c = new Closeable(){public void close(){
 			boolean b = sf.cancel(false);
 		}};
+		newLuan.registry().put(luan,luan);  // prevent gc
 		luan.registry().put(c,c);  // prevent gc
 		luan.onClose(c);
 	}