diff src/luan/host/WebHandler.java @ 1766:8df0b80e715e

fix scheduled tasks
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 06 Jun 2023 14:33:24 -0600
parents 164c6ea53147
children 9157e0d5936e
line wrap: on
line diff
--- a/src/luan/host/WebHandler.java	Fri May 26 10:29:55 2023 -0600
+++ b/src/luan/host/WebHandler.java	Tue Jun 06 14:33:24 2023 -0600
@@ -1,7 +1,14 @@
 package luan.host;
 
+import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.Set;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
 import goodjava.logging.Logger;
 import goodjava.logging.LoggerFactory;
 import goodjava.io.IoUtils;
@@ -23,6 +30,7 @@
 import luan.LuanException;
 import luan.LuanTable;
 import luan.LuanFunction;
+import luan.LuanJavaFunction;
 import luan.LuanClosure;
 import luan.LuanRuntimeException;
 import luan.modules.http.LuanHandler;
@@ -34,7 +42,7 @@
 	private static final Logger logger = LoggerFactory.getLogger(WebHandler.class);
 	private static final long days30 = 1000L*60*60*24*30;
 
-	private static final class MyHandler implements Handler {
+	private static final class MyHandler implements Handler, Closeable {
 		private final Handler handler;
 		final LuanHandler luanHandler;
 
@@ -46,6 +54,11 @@
 		@Override public Response handle(Request request) {
 			return handler.handle(request);
 		}
+
+		@Override public void close() {
+			Object obj = dontGc.remove(this);
+			luanHandler.close();
+		}
 	}
 
 	private static final DomainHandler.Factory factory = new DomainHandler.Factory() {
@@ -76,6 +89,13 @@
 			} finally {
 				LuanLogger.endThreadLogging();
 			}
+			Fns fns = new Fns();
+			try {
+				LuanTable Http = (LuanTable)luan.require("luan:http/Http.luan");
+				Http.put( luan, "dont_gc", new LuanJavaFunction(dontGcMethod,fns) );
+			} catch(LuanException e) {
+				throw new RuntimeException(e);
+			}
 			security(luan,dirStr);
 			LuanHandler luanHandler = new LuanHandler(luan,domain);
 
@@ -93,7 +113,9 @@
 			handler = new SafeHandler(handler);
 			handler = new LogHandler(handler,LogHandler.dirLogger(new File(logDir),days30));
 
-			return new MyHandler(handler,luanHandler);
+			MyHandler myHandler = new MyHandler(handler,luanHandler);
+			fns.set(myHandler);
+			return myHandler;
 		}
 	};
 
@@ -183,4 +205,39 @@
 		Luan.setSecurity(luan,security);
 	}
 
+
+	private static final Set<MyHandler> dontGc = Collections.newSetFromMap(new ConcurrentHashMap<MyHandler,Boolean>());
+	private static final Method dontGcMethod;
+	static {
+		try {
+			dontGcMethod = WebHandler.Fns.class.getMethod( "dont_gc" );
+		} catch(NoSuchMethodException e) {
+			throw new RuntimeException(e);
+		}
+	}
+	public static final class Fns {
+		private Reference<MyHandler> ref = null;
+		private boolean dont = false;
+
+		private void set(MyHandler myHandler) {
+			if( dont ) {
+				dontGc.add(myHandler);
+			} else {
+				ref = new WeakReference<MyHandler>(myHandler);
+			}
+		}
+
+		public void dont_gc() throws LuanException {
+			logger.info("dont_gc");
+			if( ref == null ) {
+				dont = true;
+			} else {
+				MyHandler mh = ref.get();
+				if( mh == null )
+					throw new LuanException("HTTP handler has been garbage collected");
+				dontGc.add(mh);
+			}
+		}
+	}
+
 }