Mercurial Hosting > luan
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); + } + } + } + }