changeset 1265:3f4644246e39

LuanHandler cleanup and add Server.serve_for_proxy
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 25 Sep 2018 19:51:34 -0600
parents d41997776788
children 05934fbf635a
files src/luan/modules/http/HttpServicer.java src/luan/modules/http/LuanHandler.java src/luan/modules/http/Server.luan
diffstat 3 files changed, 118 insertions(+), 134 deletions(-) [+]
line wrap: on
line diff
diff -r d41997776788 -r 3f4644246e39 src/luan/modules/http/HttpServicer.java
--- a/src/luan/modules/http/HttpServicer.java	Tue Sep 25 17:03:57 2018 -0600
+++ b/src/luan/modules/http/HttpServicer.java	Tue Sep 25 19:51:34 2018 -0600
@@ -4,7 +4,6 @@
 import org.slf4j.LoggerFactory;
 import luan.webserver.Request;
 import luan.webserver.Response;
-import luan.webserver.Status;
 import luan.LuanState;
 import luan.LuanFunction;
 import luan.LuanException;
@@ -16,7 +15,9 @@
 public final class HttpServicer {
 	private static final Logger logger = LoggerFactory.getLogger(HttpServicer.class);
 
-	public static Response service(LuanState luan,Request request,String modName) {
+	public static Response service(LuanState luan,Request request,String modName)
+		throws LuanException
+	{
 		try {
 			return serviceLuan(luan,request,modName);
 		} catch(LuanException e) {
@@ -24,25 +25,17 @@
 		}
 	}
 
-	private static Response handleError(LuanState luan,Request request,LuanException e) {
+	private static Response handleError(LuanState luan,Request request,LuanException e)
+		throws LuanException
+	{
 //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);
-		}
+		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()} );
 	}
 
 	private static Response serviceLuan(LuanState luan,Request request,String modName)
diff -r d41997776788 -r 3f4644246e39 src/luan/modules/http/LuanHandler.java
--- a/src/luan/modules/http/LuanHandler.java	Tue Sep 25 17:03:57 2018 -0600
+++ b/src/luan/modules/http/LuanHandler.java	Tue Sep 25 19:51:34 2018 -0600
@@ -16,6 +16,7 @@
 import org.slf4j.LoggerFactory;
 import luan.webserver.Request;
 import luan.webserver.Response;
+import luan.webserver.Status;
 import luan.webserver.Server;
 import luan.webserver.Handler;
 import luan.webserver.ResponseOutputStream;
@@ -30,114 +31,12 @@
 import luan.modules.BasicLuan;
 
 
-public final class LuanHandler implements Handler {
-
-	private class Instance implements LuanState.OnClose {
-		private final List<Reference<Closeable>> onClose;
-		private final LuanState luan;
-		private final ReadWriteLock lock = new ReentrantReadWriteLock();
-
-		Instance() {
-			onClose = new ArrayList<Reference<Closeable>>();
-			LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
-			luan = (LuanState)cloner.clone(luanInit);
-			luan.onClose = this;
-			try {
-				PackageLuan.load(luan,"site:/init.luan");
-			} catch(LuanException e) {
-				String err = e.getLuanStackTraceString();
-				logger.error(err);
-			}
-		}
-
-		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 {
-				return HttpServicer.service(luan,request,modName);
-			} finally {
-				lock.readLock().unlock();
-				thread.setName(oldName);
-			}
-		}
-
-		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 Object runLuan(String sourceText,String sourceName) throws LuanException {
-			lock.readLock().lock();
-			try {
-				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);
-				}
-			} finally {
-				lock.readLock().unlock();
-			}
-		}
-
-		public void onClose(Closeable c) {
-			synchronized(onClose) {
-				onClose.add(new WeakReference<Closeable>(c));
-			}
-		}
-
-		public void close() {
-			synchronized(onClose) {
-				for( Reference<Closeable> ref : onClose ) {
-					Closeable c = ref.get();
-					if( c != null ) {
-						try {
-							c.close();
-						} catch(IOException e) {
-							logger.error(c.toString(),e);
-						}
-					}
-				}
-				onClose.clear();
-			}
-		}
-
-		Instance cloneInstance() {
-			synchronized(luan) {
-				return new Instance(this);
-			}
-		}
-
-		private Instance(Instance instance) {
-			onClose = instance.onClose;
-			LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
-			luan = (LuanState)cloner.clone(instance.luan);
-			luan.onClose = this;
-		}
-	}
-
+public final class LuanHandler implements Handler, LuanState.OnClose {
 	private final LuanState luanInit;
 	private final Logger logger;
-	private volatile Instance instance;
+	private final ReadWriteLock lock = new ReentrantReadWriteLock();
+	private final List<Reference<Closeable>> onClose = new ArrayList<Reference<Closeable>>();
+	private volatile LuanState currentLuan;
 
 	private static final Method resetLuanMethod;
 	private static final Method evalInRootMethod;
@@ -162,8 +61,22 @@
 		} catch(LuanException e) {
 			throw new RuntimeException(e);
 		}
-		instance = new Instance();
+		currentLuan = newLuan();
 	}
+
+	private LuanState newLuan() {
+		LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
+		LuanState luan = (LuanState)cloner.clone(luanInit);
+		luan.onClose = this;
+		try {
+			PackageLuan.load(luan,"site:/init.luan");
+		} catch(LuanException e) {
+			String err = e.getLuanStackTraceString();
+			logger.error(err);
+		}
+		return luan;
+	}
+
 /*
 	public LuanState getLuan() {
 		return luan;
@@ -177,39 +90,106 @@
 	}
 
 	Response handle(Request request,String modName) {
-		return instance.handle(request,modName);
+		Thread thread = Thread.currentThread();
+		String oldName = thread.getName();
+		thread.setName(request.headers.get("host")+request.path);
+		lock.readLock().lock();
+		try {
+			return HttpServicer.service(currentLuan,request,modName);
+		} catch(LuanException e) {
+			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 );
+		} finally {
+			lock.readLock().unlock();
+			thread.setName(oldName);
+		}
+	}
+
+	public void onClose(Closeable c) {
+		synchronized(onClose) {
+			onClose.add(new WeakReference<Closeable>(c));
+		}
 	}
 
 	public void close() {
-		instance.close();
+		synchronized(onClose) {
+			for( Reference<Closeable> ref : onClose ) {
+				Closeable c = ref.get();
+				if( c != null ) {
+					try {
+						c.close();
+					} catch(IOException e) {
+						logger.error(c.toString(),e);
+					}
+				}
+			}
+			onClose.clear();
+		}
 	}
 
 	public Object call_rpc(String fnName,Object... args) throws LuanException {
-		return instance.call_rpc(fnName,args);
+		lock.readLock().lock();
+		try {
+			LuanFunction fn;
+			LuanState luan = currentLuan;
+			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() {
-				instance.lock.writeLock().lock();
+				lock.writeLock().lock();
 				try {
-					instance.close();
-					instance = new Instance();
+					close();
+					currentLuan = newLuan();
 				} finally {
-					instance.lock.writeLock().unlock();
+					lock.writeLock().unlock();
 				}
 			}
 		}.start();
 	}
 
 	public Object runLuan(String sourceText,String sourceName) throws LuanException {
-		return instance.runLuan(sourceText,sourceName);
+		lock.readLock().lock();
+		try {
+			LuanFunction fn = Luan.load(sourceText,sourceName);
+			LuanState luan = currentLuan;
+			synchronized(luan) {
+				LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL);
+				LuanState luan2 = (LuanState)cloner.clone(luan);
+				return fn.call(luan2);
+			}
+		} finally {
+			lock.readLock().unlock();
+		}
 	}
 
 	public void eval_in_root(String text) throws LuanException {
-		Instance newInstance = this.instance.cloneInstance();
-		BasicLuan.load(text,"<eval_in_root>",null).call(newInstance.luan);
-		this.instance = newInstance;
+		LuanState oldLuan = currentLuan;
+		LuanState luan;
+		synchronized(oldLuan) {
+			LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
+			luan = (LuanState)cloner.clone(oldLuan);
+		}
+		luan.onClose = this;
+		BasicLuan.load(text,"<eval_in_root>",null).call(luan);
+		currentLuan = luan;
 	}
 
 	public static void start(Server server) throws Exception {
diff -r d41997776788 -r 3f4644246e39 src/luan/modules/http/Server.luan
--- a/src/luan/modules/http/Server.luan	Tue Sep 25 17:03:57 2018 -0600
+++ b/src/luan/modules/http/Server.luan	Tue Sep 25 19:51:34 2018 -0600
@@ -79,4 +79,15 @@
 	Server.start_rpc()
 end
 
+function Server.serve_for_proxy(dir,port)
+	port = port or 8080
+	Server.init_dir(dir)
+	local handler = LuanHandler.new()
+	handler = IndexHandler.new(handler)
+	handler = ContentTypeHandler.new(handler)
+	handler = SafeHandler.new(handler)
+	Server.server = JavaServer.new(port,handler)
+	Server.start()
+end
+
 return Server