Mercurial Hosting > luan
changeset 1766:8df0b80e715e
fix scheduled tasks
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 06 Jun 2023 14:33:24 -0600 |
parents | 1ffe1e06ea55 |
children | 9157e0d5936e |
files | src/goodjava/webserver/RequestParser.java src/goodjava/webserver/handlers/DomainHandler.java src/luan/Luan.java src/luan/host/WebHandler.java src/luan/modules/Rpc.luan src/luan/modules/ThreadLuan.java src/luan/modules/http/LuanHandler.java |
diffstat | 7 files changed, 103 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/src/goodjava/webserver/RequestParser.java Fri May 26 10:29:55 2023 -0600 +++ b/src/goodjava/webserver/RequestParser.java Tue Jun 06 14:33:24 2023 -0600 @@ -21,7 +21,7 @@ void parseUrlencoded(String charset) throws ParseException, UnsupportedEncodingException { if( request.body == null ) { - logger.warn("body is null\n"+request.rawHead); + logger.info("body is null\n"+request.rawHead); return; } this.parser = new Parser(Util.toString(request.body,charset)); @@ -194,7 +194,7 @@ void parseMultipart() throws ParseException, UnsupportedEncodingException { if( request.body == null ) { - logger.warn("body is null\n"+request.rawHead); + logger.info("body is null\n"+request.rawHead); return; } String contentType = (String)request.headers.get("content-type"); @@ -274,7 +274,7 @@ // improve later void parseJson(String charset) throws UnsupportedEncodingException { if( request.body == null ) { - logger.warn("body is null\n"+request.rawHead); + logger.info("body is null\n"+request.rawHead); return; } String value = Util.toString(request.body,charset);
--- a/src/goodjava/webserver/handlers/DomainHandler.java Fri May 26 10:29:55 2023 -0600 +++ b/src/goodjava/webserver/handlers/DomainHandler.java Tue Jun 06 14:33:24 2023 -0600 @@ -9,6 +9,7 @@ import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; import goodjava.util.SoftCacheMap; +import goodjava.util.WeakCacheMap; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; import goodjava.webserver.Handler;
--- a/src/luan/Luan.java Fri May 26 10:29:55 2023 -0600 +++ b/src/luan/Luan.java Tue Jun 06 14:33:24 2023 -0600 @@ -451,7 +451,7 @@ public void check(Luan luan,LuanClosure closure,String op,Object... args) throws LuanException; } - private static String SECURITY_KEY = "Luan.Security"; + private static final String SECURITY_KEY = "Luan.Security"; public static void checkSecurity(Luan luan,String op,Object... args) throws LuanException { check(luan,1,op,args);
--- 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); + } + } + } + }
--- a/src/luan/modules/Rpc.luan Fri May 26 10:29:55 2023 -0600 +++ b/src/luan/modules/Rpc.luan Tue Jun 06 14:33:24 2023 -0600 @@ -220,7 +220,7 @@ responder.respond() end catch e - logger.warn(e) + logger.info(e) finally responder and responder.after_close and responder.after_close() end
--- a/src/luan/modules/ThreadLuan.java Fri May 26 10:29:55 2023 -0600 +++ b/src/luan/modules/ThreadLuan.java Tue Jun 06 14:33:24 2023 -0600 @@ -1,7 +1,6 @@ package luan.modules; import java.io.Closeable; -import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.HashMap; @@ -26,6 +25,11 @@ public final class ThreadLuan { private static final Logger logger = LoggerFactory.getLogger(ThreadLuan.class); + public static final String CLOSEABLES = "Luan.closeables"; + public interface Closeables { + public void addCloseable(Closeable c) throws LuanException; + } + private static final Executor exec = Executors.newCachedThreadPool(); public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); @@ -50,8 +54,6 @@ exec.execute(runnable(luan,fn)); } - private static final Map<String,ScheduledFuture> scheduleds = new WeakCacheMap<String,ScheduledFuture>(); - private static void cancel(ScheduledFuture sf,String src) { boolean b = sf.cancel(false); if( !sf.isCancelled() ) @@ -82,17 +84,13 @@ Number delay = Utils.removeNumber(options,"delay"); Number repeatingDelay = Utils.removeNumber(options,"repeating_delay"); Number repeatingRate = Utils.removeNumber(options,"repeating_rate"); - Boolean dontGc = Utils.removeBoolean(options,"dont_gc"); String id = Utils.removeString(options,"id"); + if( id != null ) + logger.error("thread option 'id' is obsolete: "+id); if( repeatingDelay!=null && repeatingRate!=null ) throw new LuanException("can't define both repeating_delay and repeating_rate"); boolean repeating = repeatingDelay!=null || repeatingRate!=null; Utils.checkEmpty(options); - if( id != null ) { - ScheduledFuture sf = scheduleds.remove(id); - if( sf != null ) - cancel(sf,"id "+id); - } final Runnable r = runnable(newLuan,fn); final ScheduledFuture sf; if( repeatingDelay != null ) { @@ -109,16 +107,18 @@ scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); return; } - if( !Boolean.TRUE.equals(dontGc) ) { - Object c = new Object() { + Closeables cs = (Closeables)luan.registry().get(CLOSEABLES); + if( cs != null ) { + Closeable cl = new Closeable() { + public void close() { + cancel(sf,"close"); + } protected void finalize() throws Throwable { - cancel(sf,"gc"); + cancel(sf,"gc"); // cancel on gc } }; - luan.registry().put(c,c); // cancel on gc + cs.addCloseable(cl); } - if( id != null ) - scheduleds.put(id,sf); }
--- a/src/luan/modules/http/LuanHandler.java Fri May 26 10:29:55 2023 -0600 +++ b/src/luan/modules/http/LuanHandler.java Tue Jun 06 14:33:24 2023 -0600 @@ -10,9 +10,6 @@ import java.net.BindException; import java.util.List; import java.util.ArrayList; -import java.util.Set; -import java.util.Collections; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import goodjava.logging.Logger; @@ -30,32 +27,30 @@ import luan.LuanException; import luan.modules.PackageLuan; import luan.modules.BasicLuan; +import luan.modules.ThreadLuan; import luan.modules.logging.LuanLogger; public final class LuanHandler implements Handler, Closeable { private static final Logger logger = LoggerFactory.getLogger(LuanHandler.class); - private static final Set<LuanHandler> dontGc = Collections.newSetFromMap(new ConcurrentHashMap<LuanHandler,Boolean>()); - private final Luan luanInit; private final String domain; private final ReadWriteLock rwLock = new ReentrantReadWriteLock(); private volatile Luan currentLuan; private volatile boolean isDisabled = false; private volatile boolean didInit; + private final List<Closeable> closeables = new ArrayList<Closeable>(); private static final Method resetLuanMethod; private static final Method evalInRootMethod; private static final Method disableLuanMethod; - private static final Method dontGcMethod; private static final Method testAsInitMethod; static { try { resetLuanMethod = LuanHandler.Fns.class.getMethod( "reset_luan" ); evalInRootMethod = LuanHandler.Fns.class.getMethod( "eval_in_root", String.class ); disableLuanMethod = LuanHandler.Fns.class.getMethod( "disable_luan" ); - dontGcMethod = LuanHandler.Fns.class.getMethod( "dont_gc" ); testAsInitMethod = LuanHandler.Fns.class.getMethod( "test_as_init", String.class, String.class ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); @@ -65,26 +60,28 @@ public LuanHandler(Luan luanInit,String domain) { this.luanInit = luanInit; this.domain = domain; + Fns fns = new Fns(this); try { - Fns fns = new Fns(this); LuanTable Http = (LuanTable)luanInit.require("luan:http/Http.luan"); if( Http.get(luanInit,"reset_luan") == null ) Http.put( luanInit, "reset_luan", new LuanJavaFunction(resetLuanMethod,fns) ); Http.put( luanInit, "eval_in_root", new LuanJavaFunction(evalInRootMethod,fns) ); Http.put( luanInit, "disable_luan", new LuanJavaFunction(disableLuanMethod,fns) ); - Http.put( luanInit, "dont_gc", new LuanJavaFunction(dontGcMethod,fns) ); Http.put( luanInit, "test_as_init", new LuanJavaFunction(testAsInitMethod,fns) ); } catch(LuanException e) { throw new RuntimeException(e); } + if( luanInit.registry().get(ThreadLuan.CLOSEABLES) != null ) + throw new RuntimeException(ThreadLuan.CLOSEABLES+" already set"); + luanInit.registry().put(ThreadLuan.CLOSEABLES,fns); if( domain != null ) - logger.info("new "+domain); + logger.warn("new "+domain); newLuan(); } protected void finalize() throws Throwable { if( domain != null ) - logger.info("gc "+domain); + logger.warn("gc "+domain); } private void init(Luan luan) throws LuanException { @@ -146,9 +143,16 @@ } } - public void close() { - Object obj = dontGc.remove(this); - //logger.info("close "+domain+" "+(obj!=null)); + @Override public void close() { + synchronized(currentLuan) { + for( Closeable c : closeables ) { + try { + c.close(); + } catch(IOException e) { + logger.error(c.toString(),e); + } + } + } } public Object call_rpc(String fnName,Object... args) throws LuanException { @@ -215,12 +219,7 @@ } } - private void dont_gc() { - dontGc.add(this); - //logger.info("dont_gc "+domain); - } - - public static final class Fns { + public static final class Fns implements ThreadLuan.Closeables { private final Reference<LuanHandler> ref; private Fns(LuanHandler lh) { @@ -234,6 +233,10 @@ return lh; } + @Override public void addCloseable(Closeable c) throws LuanException { + lh().closeables.add(c); + } + public void reset_luan() throws LuanException { lh().reset_luan(); } @@ -246,10 +249,6 @@ lh().eval_in_root(text); } - public void dont_gc() throws LuanException { - lh().dont_gc(); - } - public void test_as_init(String text,String sourceName) throws LuanException { lh().test_as_init(text,sourceName); }