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