Mercurial Hosting > luan
view src/luan/modules/http/LuanHandler.java @ 1004:3fa54d9d19cd
better handling of BindException
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sat, 22 Oct 2016 23:00:57 -0600 |
parents | 32d4b569567c |
children | 0d884377e923 |
line wrap: on
line source
package luan.modules.http; 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 javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AbstractHandler; 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 extends AbstractHandler { private final LuanState luanInit; private final Logger logger; private String welcomeFile = "index.html"; 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); } } @Override public void handle(String target,Request request,HttpServletResponse response) throws IOException { //Thread.dumpStack(); if( target.endsWith("/") ) target += welcomeFile; Thread thread = Thread.currentThread(); String oldName = thread.getName(); thread.setName(request.getHeader("host")+request.getRequestURI()); lock.readLock().lock(); try { if( !HttpServicer.service(luan,request,response,"site:"+target+".luan") ) return; } catch(LuanException e) { //e.printStackTrace(); String err = e.getFullMessage(); logger.error(err); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,err); } finally { lock.readLock().unlock(); thread.setName(oldName); } request.setHandled(true); } public void setWelcomeFile(String welcomeFile) { this.welcomeFile = welcomeFile; } @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(); } /* @Override public void destroy() { System.out.println("qqqqqqqqqqqqqqqqqqqq destroy "+this); super.destroy(); } */ 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.getFullMessage(); 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()); } } }