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