comparison src/luan/modules/http/LuanHandler.java @ 1766:8df0b80e715e

fix scheduled tasks
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 06 Jun 2023 14:33:24 -0600
parents d6ec67fa4a61
children 9157e0d5936e
comparison
equal deleted inserted replaced
1765:1ffe1e06ea55 1766:8df0b80e715e
8 import java.lang.ref.WeakReference; 8 import java.lang.ref.WeakReference;
9 import java.lang.reflect.Method; 9 import java.lang.reflect.Method;
10 import java.net.BindException; 10 import java.net.BindException;
11 import java.util.List; 11 import java.util.List;
12 import java.util.ArrayList; 12 import java.util.ArrayList;
13 import java.util.Set;
14 import java.util.Collections;
15 import java.util.concurrent.ConcurrentHashMap;
16 import java.util.concurrent.locks.ReadWriteLock; 13 import java.util.concurrent.locks.ReadWriteLock;
17 import java.util.concurrent.locks.ReentrantReadWriteLock; 14 import java.util.concurrent.locks.ReentrantReadWriteLock;
18 import goodjava.logging.Logger; 15 import goodjava.logging.Logger;
19 import goodjava.logging.LoggerFactory; 16 import goodjava.logging.LoggerFactory;
20 import goodjava.webserver.Request; 17 import goodjava.webserver.Request;
28 import luan.LuanFunction; 25 import luan.LuanFunction;
29 import luan.LuanJavaFunction; 26 import luan.LuanJavaFunction;
30 import luan.LuanException; 27 import luan.LuanException;
31 import luan.modules.PackageLuan; 28 import luan.modules.PackageLuan;
32 import luan.modules.BasicLuan; 29 import luan.modules.BasicLuan;
30 import luan.modules.ThreadLuan;
33 import luan.modules.logging.LuanLogger; 31 import luan.modules.logging.LuanLogger;
34 32
35 33
36 public final class LuanHandler implements Handler, Closeable { 34 public final class LuanHandler implements Handler, Closeable {
37 private static final Logger logger = LoggerFactory.getLogger(LuanHandler.class); 35 private static final Logger logger = LoggerFactory.getLogger(LuanHandler.class);
38
39 private static final Set<LuanHandler> dontGc = Collections.newSetFromMap(new ConcurrentHashMap<LuanHandler,Boolean>());
40 36
41 private final Luan luanInit; 37 private final Luan luanInit;
42 private final String domain; 38 private final String domain;
43 private final ReadWriteLock rwLock = new ReentrantReadWriteLock(); 39 private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
44 private volatile Luan currentLuan; 40 private volatile Luan currentLuan;
45 private volatile boolean isDisabled = false; 41 private volatile boolean isDisabled = false;
46 private volatile boolean didInit; 42 private volatile boolean didInit;
43 private final List<Closeable> closeables = new ArrayList<Closeable>();
47 44
48 private static final Method resetLuanMethod; 45 private static final Method resetLuanMethod;
49 private static final Method evalInRootMethod; 46 private static final Method evalInRootMethod;
50 private static final Method disableLuanMethod; 47 private static final Method disableLuanMethod;
51 private static final Method dontGcMethod;
52 private static final Method testAsInitMethod; 48 private static final Method testAsInitMethod;
53 static { 49 static {
54 try { 50 try {
55 resetLuanMethod = LuanHandler.Fns.class.getMethod( "reset_luan" ); 51 resetLuanMethod = LuanHandler.Fns.class.getMethod( "reset_luan" );
56 evalInRootMethod = LuanHandler.Fns.class.getMethod( "eval_in_root", String.class ); 52 evalInRootMethod = LuanHandler.Fns.class.getMethod( "eval_in_root", String.class );
57 disableLuanMethod = LuanHandler.Fns.class.getMethod( "disable_luan" ); 53 disableLuanMethod = LuanHandler.Fns.class.getMethod( "disable_luan" );
58 dontGcMethod = LuanHandler.Fns.class.getMethod( "dont_gc" );
59 testAsInitMethod = LuanHandler.Fns.class.getMethod( "test_as_init", String.class, String.class ); 54 testAsInitMethod = LuanHandler.Fns.class.getMethod( "test_as_init", String.class, String.class );
60 } catch(NoSuchMethodException e) { 55 } catch(NoSuchMethodException e) {
61 throw new RuntimeException(e); 56 throw new RuntimeException(e);
62 } 57 }
63 } 58 }
64 59
65 public LuanHandler(Luan luanInit,String domain) { 60 public LuanHandler(Luan luanInit,String domain) {
66 this.luanInit = luanInit; 61 this.luanInit = luanInit;
67 this.domain = domain; 62 this.domain = domain;
68 try { 63 Fns fns = new Fns(this);
69 Fns fns = new Fns(this); 64 try {
70 LuanTable Http = (LuanTable)luanInit.require("luan:http/Http.luan"); 65 LuanTable Http = (LuanTable)luanInit.require("luan:http/Http.luan");
71 if( Http.get(luanInit,"reset_luan") == null ) 66 if( Http.get(luanInit,"reset_luan") == null )
72 Http.put( luanInit, "reset_luan", new LuanJavaFunction(resetLuanMethod,fns) ); 67 Http.put( luanInit, "reset_luan", new LuanJavaFunction(resetLuanMethod,fns) );
73 Http.put( luanInit, "eval_in_root", new LuanJavaFunction(evalInRootMethod,fns) ); 68 Http.put( luanInit, "eval_in_root", new LuanJavaFunction(evalInRootMethod,fns) );
74 Http.put( luanInit, "disable_luan", new LuanJavaFunction(disableLuanMethod,fns) ); 69 Http.put( luanInit, "disable_luan", new LuanJavaFunction(disableLuanMethod,fns) );
75 Http.put( luanInit, "dont_gc", new LuanJavaFunction(dontGcMethod,fns) );
76 Http.put( luanInit, "test_as_init", new LuanJavaFunction(testAsInitMethod,fns) ); 70 Http.put( luanInit, "test_as_init", new LuanJavaFunction(testAsInitMethod,fns) );
77 } catch(LuanException e) { 71 } catch(LuanException e) {
78 throw new RuntimeException(e); 72 throw new RuntimeException(e);
79 } 73 }
74 if( luanInit.registry().get(ThreadLuan.CLOSEABLES) != null )
75 throw new RuntimeException(ThreadLuan.CLOSEABLES+" already set");
76 luanInit.registry().put(ThreadLuan.CLOSEABLES,fns);
80 if( domain != null ) 77 if( domain != null )
81 logger.info("new "+domain); 78 logger.warn("new "+domain);
82 newLuan(); 79 newLuan();
83 } 80 }
84 81
85 protected void finalize() throws Throwable { 82 protected void finalize() throws Throwable {
86 if( domain != null ) 83 if( domain != null )
87 logger.info("gc "+domain); 84 logger.warn("gc "+domain);
88 } 85 }
89 86
90 private void init(Luan luan) throws LuanException { 87 private void init(Luan luan) throws LuanException {
91 if( didInit ) 88 if( didInit )
92 return; 89 return;
144 rwLock.readLock().unlock(); 141 rwLock.readLock().unlock();
145 thread.setName(oldName); 142 thread.setName(oldName);
146 } 143 }
147 } 144 }
148 145
149 public void close() { 146 @Override public void close() {
150 Object obj = dontGc.remove(this); 147 synchronized(currentLuan) {
151 //logger.info("close "+domain+" "+(obj!=null)); 148 for( Closeable c : closeables ) {
149 try {
150 c.close();
151 } catch(IOException e) {
152 logger.error(c.toString(),e);
153 }
154 }
155 }
152 } 156 }
153 157
154 public Object call_rpc(String fnName,Object... args) throws LuanException { 158 public Object call_rpc(String fnName,Object... args) throws LuanException {
155 rwLock.readLock().lock(); 159 rwLock.readLock().lock();
156 LuanLogger.startThreadLogging(currentLuan); 160 LuanLogger.startThreadLogging(currentLuan);
213 synchronized(currentLuan) { 217 synchronized(currentLuan) {
214 currentLuan.load(text,"<eval_in_root>",false,null).call(currentLuan); 218 currentLuan.load(text,"<eval_in_root>",false,null).call(currentLuan);
215 } 219 }
216 } 220 }
217 221
218 private void dont_gc() { 222 public static final class Fns implements ThreadLuan.Closeables {
219 dontGc.add(this);
220 //logger.info("dont_gc "+domain);
221 }
222
223 public static final class Fns {
224 private final Reference<LuanHandler> ref; 223 private final Reference<LuanHandler> ref;
225 224
226 private Fns(LuanHandler lh) { 225 private Fns(LuanHandler lh) {
227 this.ref = new WeakReference<LuanHandler>(lh); 226 this.ref = new WeakReference<LuanHandler>(lh);
228 } 227 }
232 if( lh == null ) 231 if( lh == null )
233 throw new LuanException("HTTP handler has been garbage collected"); 232 throw new LuanException("HTTP handler has been garbage collected");
234 return lh; 233 return lh;
235 } 234 }
236 235
236 @Override public void addCloseable(Closeable c) throws LuanException {
237 lh().closeables.add(c);
238 }
239
237 public void reset_luan() throws LuanException { 240 public void reset_luan() throws LuanException {
238 lh().reset_luan(); 241 lh().reset_luan();
239 } 242 }
240 243
241 public void disable_luan() throws LuanException { 244 public void disable_luan() throws LuanException {
242 lh().disable_luan(); 245 lh().disable_luan();
243 } 246 }
244 247
245 public void eval_in_root(String text) throws LuanException { 248 public void eval_in_root(String text) throws LuanException {
246 lh().eval_in_root(text); 249 lh().eval_in_root(text);
247 }
248
249 public void dont_gc() throws LuanException {
250 lh().dont_gc();
251 } 250 }
252 251
253 public void test_as_init(String text,String sourceName) throws LuanException { 252 public void test_as_init(String text,String sourceName) throws LuanException {
254 lh().test_as_init(text,sourceName); 253 lh().test_as_init(text,sourceName);
255 } 254 }