changeset 1263:382c444a6c77

add Http.eval_in_root and Http.handle_error
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 24 Sep 2018 22:06:25 -0600
parents 81d3a01fbd09
children d41997776788
files src/luan/host/WebHandler.java src/luan/modules/http/Http.luan src/luan/modules/http/HttpServicer.java src/luan/modules/http/LuanHandler.java
diffstat 4 files changed, 68 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/host/WebHandler.java	Mon Sep 24 14:48:59 2018 -0600
+++ b/src/luan/host/WebHandler.java	Mon Sep 24 22:06:25 2018 -0600
@@ -165,7 +165,7 @@
 		LuanTable init = initLuan(luan,dir,domain);
 
 		String loggerRoot = (String)init.rawGet("logger_root");
-		LuanHandler luanHandler = new LuanHandler(luan,loggerRoot,null);
+		LuanHandler luanHandler = new LuanHandler(luan,loggerRoot);
 		NotFound notFoundHandler = new NotFound(luanHandler);
 
 		Handler handler = luanHandler;
--- a/src/luan/modules/http/Http.luan	Mon Sep 24 14:48:59 2018 -0600
+++ b/src/luan/modules/http/Http.luan	Mon Sep 24 22:06:25 2018 -0600
@@ -13,6 +13,7 @@
 local String = require "luan:String.luan"
 local lower = String.lower or error()
 local matches = String.matches or error()
+local trim = String.trim or error()
 local IoLuan = require "java:luan.modules.IoLuan"
 local LuanJava = require "java:luan.Luan"
 local Request = require "java:luan.webserver.Request"
@@ -21,6 +22,8 @@
 local Status = require "java:luan.webserver.Status"
 local OutputStreamWriter = require "java:java.io.OutputStreamWriter"
 local HashMap = require "java:java.util.HashMap"
+local Logging = require "luan:logging/Logging.luan"
+local logger = Logging.logger "Http"
 
 
 local Http = {}
@@ -157,4 +160,16 @@
 	return java
 end
 
+function Http.error_priority(java_request,e)
+	return "error"
+end
+
+function Http.handle_error(java_request,e)
+	local call = Http.error_priority(java_request,e)
+	local err = e.get_stack_trace_string()
+	logger[call](err.."\n"..trim(java_request.rawHead).."\n")
+	local msg = "Internel Server Error\n\n"..err
+	return Response.errorResponse( Status.INTERNAL_SERVER_ERROR, msg )
+end
+
 return Http
--- a/src/luan/modules/http/HttpServicer.java	Mon Sep 24 14:48:59 2018 -0600
+++ b/src/luan/modules/http/HttpServicer.java	Mon Sep 24 22:06:25 2018 -0600
@@ -13,31 +13,43 @@
 import luan.modules.PackageLuan;
 
 
-public class HttpServicer {
+public final class HttpServicer {
 	private static final Logger logger = LoggerFactory.getLogger(HttpServicer.class);
 
-	public Response service(LuanState luan,Request request,String modName) {
+	public static Response service(LuanState luan,Request request,String modName) {
 		try {
 			return serviceLuan(luan,request,modName);
 		} catch(LuanException e) {
-			return handleError(request,e);
+			return handleError(luan,request,e);
 		}
 	}
 
-	protected Response handleError(Request request,LuanException e) {
+	private static Response handleError(LuanState luan,Request request,LuanException e) {
 //e.printStackTrace();
+/*
 		String err = e.getLuanStackTraceString();
 		logger.error(err+"\n"+request.rawHead.trim()+"\n");
 		String msg = "Internel Server Error\n\n" + err;
 		return Response.errorResponse( Status.INTERNAL_SERVER_ERROR, msg );
+*/
+		synchronized(luan) {
+			LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL);
+			luan = (LuanState)cloner.clone(luan);
+		}
+		try {
+			LuanTable module = (LuanTable)PackageLuan.require(luan,"luan:http/Http.luan");
+			LuanFunction fn = (LuanFunction)module.rawGet("handle_error");
+			return (Response)fn.call( luan, new Object[]{request,e.table()} );
+		} catch(LuanException e2) {
+			throw new RuntimeException(e2);
+		}
 	}
 
-	protected Response serviceLuan(LuanState luan,Request request,String modName)
+	private static Response serviceLuan(LuanState luan,Request request,String modName)
 		throws LuanException
 	{
 		LuanFunction fn;
 		synchronized(luan) {
-			inSinchronized(luan,request);
 			PackageLuan.enableLoad(luan,"luan:http/Http.luan",modName);
 			PackageLuan.require(luan,"luan:http/Http.luan");
 			Object mod = PackageLuan.load(luan,modName);
@@ -67,8 +79,5 @@
 		return response;
 	}
 
-	protected void inSinchronized(LuanState luan,Request request)
-		throws LuanException
-	{}
-
+	private HttpServicer() {}  // never
 }
--- a/src/luan/modules/http/LuanHandler.java	Mon Sep 24 14:48:59 2018 -0600
+++ b/src/luan/modules/http/LuanHandler.java	Mon Sep 24 22:06:25 2018 -0600
@@ -6,8 +6,6 @@
 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;
@@ -23,25 +21,26 @@
 import luan.LuanCloner;
 import luan.LuanException;
 import luan.modules.PackageLuan;
+import luan.modules.BasicLuan;
 
 
-public class LuanHandler implements Handler, Closeable {
+public final class LuanHandler implements Handler, Closeable {
 	private final LuanState luanInit;
 	private final Logger logger;
-	private final HttpServicer httpServicer;
-	private final ReadWriteLock lock = new ReentrantReadWriteLock();
-	private LuanState luan;
+	private volatile LuanState luan;
 
 	private static final Method resetLuanMethod;
+	private static final Method evalInRootMethod;
 	static {
 		try {
-			resetLuanMethod = LuanHandler.class.getMethod("reset_luan");
+			resetLuanMethod = LuanHandler.class.getMethod( "reset_luan" );
+			evalInRootMethod = LuanHandler.class.getMethod( "eval_in_root", String.class );
 		} catch(NoSuchMethodException e) {
 			throw new RuntimeException(e);
 		}
 	}
 
-	public LuanHandler(LuanState luanInit,String loggerRoot,HttpServicer httpServicer) {
+	public LuanHandler(LuanState luanInit,String loggerRoot) {
 		this.luanInit = luanInit;
 		if( loggerRoot==null )
 			loggerRoot = "";
@@ -49,10 +48,10 @@
 		try {
 			LuanTable Http = (LuanTable)PackageLuan.require(luanInit,"luan:http/Http.luan");
 			Http.rawPut( "reset_luan", new LuanJavaFunction(resetLuanMethod,this) );
+			Http.rawPut( "eval_in_root", new LuanJavaFunction(evalInRootMethod,this) );
 		} catch(LuanException e) {
 			throw new RuntimeException(e);
 		}
-		this.httpServicer = httpServicer!=null ? httpServicer : new HttpServicer();
 		setLuan();
 		luanInit.onClose(this);
 	}
@@ -83,11 +82,9 @@
 		Thread thread = Thread.currentThread();
 		String oldName = thread.getName();
 		thread.setName(request.headers.get("host")+request.path);
-		lock.readLock().lock();
 		try {
-			return httpServicer.service(luan,request,modName);
+			return HttpServicer.service(luan,request,modName);
 		} finally {
-			lock.readLock().unlock();
 			thread.setName(oldName);
 		}
 	}
@@ -99,41 +96,24 @@
 	}
 
 	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();
+		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);
 	}
 
 	public void reset_luan() {
-		new Thread() {
-			public void run() {
-				lock.writeLock().lock();
-				try {
-					synchronized(luan) {
-						luan.close();
-						setLuan();
-					}
-				} finally {
-					lock.writeLock().unlock();
-				}
-			}
-		}.start();
+		setLuan();
 	}
 
 	public Object runLuan(String sourceText,String sourceName) throws LuanException {
@@ -145,6 +125,16 @@
 		}
 	}
 
+	public void eval_in_root(String text) throws LuanException {
+		LuanState luan;
+		synchronized(this.luan) {
+			LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
+			luan = (LuanState)cloner.clone(this.luan);
+		}
+		BasicLuan.load(text,"<eval_in_root>",null).call(luan);
+		this.luan = luan;
+	}
+
 	public static void start(Server server) throws Exception {
 		try {
 			server.start();