Mercurial Hosting > luan
diff src/luan/modules/http/LuanHandler.java @ 1171:794ddcfbee20
remove http/impl
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 11 Feb 2018 02:41:23 -0700 |
parents | src/luan/modules/http/impl/LuanHandler.java@3a0f58d09ee7 |
children | 94cf2576a922 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/http/LuanHandler.java Sun Feb 11 02:41:23 2018 -0700 @@ -0,0 +1,167 @@ +package luan.modules.http; + +import java.io.Writer; +import java.io.PrintWriter; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.BindException; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import luan.webserver.Request; +import luan.webserver.Response; +import luan.webserver.Server; +import luan.webserver.Handler; +import luan.webserver.Status; +import luan.webserver.ResponseOutputStream; +import luan.Luan; +import luan.LuanState; +import luan.LuanTable; +import luan.LuanFunction; +import luan.LuanJavaFunction; +import luan.LuanCloner; +import luan.LuanException; +import luan.modules.PackageLuan; + + +public class LuanHandler implements Handler { + private final LuanState luanInit; + private final Logger logger; + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private LuanState luan; + + private static final Method resetLuanMethod; + static { + try { + resetLuanMethod = LuanHandler.class.getMethod("reset_luan"); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + public LuanHandler(LuanState luan,String loggerRoot) { + this.luanInit = luan; + if( loggerRoot==null ) + loggerRoot = ""; + logger = LoggerFactory.getLogger(loggerRoot+LuanHandler.class.getName()); + try { + LuanTable Http = (LuanTable)PackageLuan.require(luanInit,"luan:http/Http.luan"); + Http.rawPut( "reset_luan", new LuanJavaFunction(resetLuanMethod,this) ); + } catch(LuanException e) { + throw new RuntimeException(e); + } + setLuan(); + } + + @Override public Response handle(Request request) { + if( request.path.endsWith("/") ) + return null; + String modName = "site:" + request.path +".luan"; + return handle(request,modName); + } + + Response handle(Request request,String modName) { + Thread thread = Thread.currentThread(); + String oldName = thread.getName(); + thread.setName(request.headers.get("host")+request.path); + lock.readLock().lock(); + try { + Response response = HttpServicer.service(luan,request,modName); + return response; + } catch(LuanException e) { +//e.printStackTrace(); + String err = e.getLuanStackTraceString(); + logger.error(err); + String msg = "Internel Server Error\n\n" + err; + return Response.errorResponse( Status.INTERNAL_SERVER_ERROR, msg ); + } finally { + lock.readLock().unlock(); + thread.setName(oldName); + } + } +/* + @Override protected void doStart() throws Exception { +// Thread.dumpStack(); +//System.out.println("qqqqqqqqqqqqqqqqqqqq doStart "+this); + setLuan(); + super.doStart(); + } + + @Override protected void doStop() throws Exception { + synchronized(luan) { + luan.close(); + } +//System.out.println("qqqqqqqqqqqqqqqqqqqq doStop "+this); + super.doStop(); + } +*/ + public Object call_rpc(String fnName,Object... args) throws LuanException { + lock.readLock().lock(); + try { + LuanFunction fn; + LuanState luan = this.luan; + synchronized(luan) { + PackageLuan.enableLoad(luan,"luan:Rpc.luan"); + LuanTable rpc = (LuanTable)PackageLuan.require(luan,"luan:Rpc.luan"); + LuanTable fns = (LuanTable)rpc.get(luan,"functions"); + fn = (LuanFunction)fns.get(luan,fnName); + if( fn == null ) + throw new LuanException( "function not found: " + fnName ); + LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); + luan = (LuanState)cloner.clone(luan); + fn = (LuanFunction)cloner.get(fn); + } + return fn.call(luan,args); + } finally { + lock.readLock().unlock(); + } + } + + public void reset_luan() { + new Thread() { + public void run() { + lock.writeLock().lock(); + try { + synchronized(luan) { + luan.close(); + setLuan(); + } + } catch(IOException e) { + logger.error("reset_luan failed",e); + } finally { + lock.writeLock().unlock(); + } + } + }.start(); + } + + private void setLuan() { + LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); + luan = (LuanState)cloner.clone(luanInit); + try { + PackageLuan.load(luan,"site:/init.luan"); + } catch(LuanException e) { + String err = e.getLuanStackTraceString(); + logger.error(err); + } + } + + public Object runLuan(String sourceText,String sourceName) throws LuanException { + LuanFunction fn = Luan.load(sourceText,sourceName); + synchronized(luan) { + LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL); + LuanState luan = (LuanState)cloner.clone(this.luan); + return fn.call(luan); + } + } + + public static void start(Server server) throws Exception { + try { + server.start(); + } catch(BindException e) { + throw new LuanException(e.toString()); + } + } + +}