comparison src/luan/modules/http/LuanHandler.java @ 1578:c922446f53aa

immutable threading
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 08 Feb 2021 14:16:19 -0700
parents 8fbcc4747091
children 2975c932864d
comparison
equal deleted inserted replaced
1577:60e5c324adf9 1578:c922446f53aa
25 import goodjava.webserver.ResponseOutputStream; 25 import goodjava.webserver.ResponseOutputStream;
26 import luan.Luan; 26 import luan.Luan;
27 import luan.LuanTable; 27 import luan.LuanTable;
28 import luan.LuanFunction; 28 import luan.LuanFunction;
29 import luan.LuanJavaFunction; 29 import luan.LuanJavaFunction;
30 import luan.LuanCloner;
31 import luan.LuanException; 30 import luan.LuanException;
32 import luan.modules.PackageLuan; 31 import luan.modules.PackageLuan;
33 import luan.modules.BasicLuan; 32 import luan.modules.BasicLuan;
34 import luan.modules.logging.LuanLogger; 33 import luan.modules.logging.LuanLogger;
35 34
85 } 84 }
86 85
87 private Luan newLuan() { 86 private Luan newLuan() {
88 Luan luan; 87 Luan luan;
89 synchronized(luanInit) { 88 synchronized(luanInit) {
90 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); 89 luan = new Luan(luanInit);
91 luan = (Luan)cloner.clone(luanInit);
92 } 90 }
93 LuanLogger.startThreadLogging(luan); 91 LuanLogger.startThreadLogging(luan);
94 try { 92 try {
95 PackageLuan.load(luan,"site:/init.luan"); 93 PackageLuan.load(luan,"site:/init.luan");
96 } catch(LuanException e) { 94 } catch(LuanException e) {
136 public void close() { 134 public void close() {
137 Object obj = dontGc.remove(this); 135 Object obj = dontGc.remove(this);
138 //logger.info("close "+domain+" "+(obj!=null)); 136 //logger.info("close "+domain+" "+(obj!=null));
139 } 137 }
140 138
141 public Object call_rpc(Luan luan,String fnName,Object... args) throws LuanException { 139 public Object call_rpc(String fnName,Object... args) throws LuanException {
142 rwLock.readLock().lock(); 140 rwLock.readLock().lock();
143 LuanLogger.startThreadLogging(currentLuan); 141 LuanLogger.startThreadLogging(currentLuan);
144 try { 142 try {
145 LuanFunction fn; 143 LuanFunction fn;
146 synchronized(luanInit) { 144 Luan luan;
147 enableLoad("luan:Rpc.luan"); 145 synchronized(currentLuan) {
148 LuanTable rpc = (LuanTable)currentLuan.require("luan:Rpc.luan"); 146 LuanTable rpc = (LuanTable)currentLuan.require("luan:Rpc.luan");
149 LuanTable fns = (LuanTable)rpc.get(luan,"functions"); 147 LuanTable fns = (LuanTable)rpc.get(currentLuan,"functions");
150 fn = (LuanFunction)fns.get(luan,fnName); 148 fn = (LuanFunction)fns.get(currentLuan,fnName);
151 if( fn == null ) 149 if( fn == null )
152 throw new LuanException( "function not found: " + fnName ); 150 throw new LuanException( "function not found: " + fnName );
153 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); 151 luan = new Luan(currentLuan);
154 fn = (LuanFunction)cloner.get(fn);
155 } 152 }
156 return fn.call(luan,args); 153 return fn.call(luan,args);
157 } finally { 154 } finally {
158 LuanLogger.endThreadLogging(); 155 LuanLogger.endThreadLogging();
159 rwLock.readLock().unlock(); 156 rwLock.readLock().unlock();
183 private void disable_luan() { 180 private void disable_luan() {
184 isDisabled = true; 181 isDisabled = true;
185 } 182 }
186 183
187 private void eval_in_root(String text) throws LuanException { 184 private void eval_in_root(String text) throws LuanException {
188 Luan luan; 185 synchronized(currentLuan) {
189 synchronized(luanInit) { 186 currentLuan.load(text,"<eval_in_root>",false,null).call(currentLuan);
190 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); 187 }
191 luan = (Luan)cloner.clone(currentLuan);
192 }
193 luan.load(text,"<eval_in_root>",false,null).call(luan);
194 currentLuan = luan;
195 } 188 }
196 189
197 private void dont_gc() { 190 private void dont_gc() {
198 dontGc.add(this); 191 dontGc.add(this);
199 //logger.info("dont_gc "+domain); 192 //logger.info("dont_gc "+domain);
247 } 240 }
248 241
249 private Response handleError(Request request,LuanException e) 242 private Response handleError(Request request,LuanException e)
250 throws LuanException 243 throws LuanException
251 { 244 {
252 //e.printStackTrace(); 245 //e.printStackTrace();
253 Luan luan; 246 Luan luan;
254 synchronized(luanInit) { 247 synchronized(currentLuan) {
255 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); 248 luan = new Luan(currentLuan);
256 luan = (Luan)cloner.clone(currentLuan);
257 } 249 }
258 LuanTable module = (LuanTable)luan.require("luan:http/Http.luan"); 250 LuanTable module = (LuanTable)luan.require("luan:http/Http.luan");
259 return (Response)module.fn("handle_error").call( luan, request, e.table(luan) ); 251 return (Response)module.fn("handle_error").call( luan, request, e.table(luan) );
260 } 252 }
261 253
263 throws LuanException 255 throws LuanException
264 { 256 {
265 String modName = "site:" + request.path +".luan"; 257 String modName = "site:" + request.path +".luan";
266 LuanFunction fn; 258 LuanFunction fn;
267 Luan luan; 259 Luan luan;
268 synchronized(luanInit) { 260 synchronized(currentLuan) {
269 enableLoad("luan:http/Http.luan",modName);
270 currentLuan.require("luan:http/Http.luan"); 261 currentLuan.require("luan:http/Http.luan");
271 Object mod = PackageLuan.load(currentLuan,modName); 262 Object mod = PackageLuan.load(currentLuan,modName);
272 if( mod.equals(Boolean.FALSE) ) 263 if( mod.equals(Boolean.FALSE) )
273 return null; 264 return null;
274 if( !(mod instanceof LuanFunction) ) 265 if( !(mod instanceof LuanFunction) )
275 throw new LuanException( "module '"+modName+"' must return a function" ); 266 throw new LuanException( "module '"+modName+"' must return a function" );
276 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); 267 luan = new Luan(currentLuan);
277 luan = (Luan)cloner.clone(currentLuan); 268 fn = (LuanFunction)mod;
278 fn = (LuanFunction)cloner.get(mod);
279 } 269 }
280 LuanTable module = (LuanTable)luan.require("luan:http/Http.luan"); 270 LuanTable module = (LuanTable)luan.require("luan:http/Http.luan");
281 module.fn("new_request").call(luan,request); 271 module.fn("new_request").call(luan,request);
282 module.fn("new_response").call(luan); 272 module.fn("new_response").call(luan);
283 fn.call(luan); 273 fn.call(luan);
287 private Response serviceNotFound(Request request) 277 private Response serviceNotFound(Request request)
288 throws LuanException 278 throws LuanException
289 { 279 {
290 LuanFunction fn; 280 LuanFunction fn;
291 Luan luan; 281 Luan luan;
292 synchronized(luanInit) { 282 synchronized(currentLuan) {
293 enableLoad("luan:http/Http.luan");
294 LuanTable module = (LuanTable)currentLuan.require("luan:http/Http.luan"); 283 LuanTable module = (LuanTable)currentLuan.require("luan:http/Http.luan");
295 fn = module.fn("not_found_handler"); 284 fn = module.fn("not_found_handler");
296 if( fn == null ) 285 if( fn == null )
297 return null; 286 return null;
298 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); 287 luan = new Luan(currentLuan);
299 luan = (Luan)cloner.clone(currentLuan);
300 fn = (LuanFunction)cloner.get(fn);
301 } 288 }
302 LuanTable module = (LuanTable)luan.require("luan:http/Http.luan"); 289 LuanTable module = (LuanTable)luan.require("luan:http/Http.luan");
303 module.fn("new_request").call(luan,request); 290 module.fn("new_request").call(luan,request);
304 module.fn("new_response").call(luan); 291 module.fn("new_response").call(luan);
305 Object obj = Luan.first(fn.call(luan)); 292 Object obj = Luan.first(fn.call(luan));
307 throw new LuanException("not_found_handler must return boolean"); 294 throw new LuanException("not_found_handler must return boolean");
308 boolean handled = (Boolean)obj; 295 boolean handled = (Boolean)obj;
309 return handled ? (Response)module.fn("finish").call(luan) : null; 296 return handled ? (Response)module.fn("finish").call(luan) : null;
310 } 297 }
311 298
312 private void enableLoad(String... mods) throws LuanException {
313 LuanTable loaded = PackageLuan.loaded(currentLuan);
314 for( String mod : mods ) {
315 if( loaded.rawGet(mod) == null ) {
316 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
317 currentLuan = (Luan)cloner.clone(currentLuan);
318 break;
319 }
320 }
321 }
322
323 } 299 }