comparison src/luan/modules/http/jetty/LuanHandler.java @ 1136:d30d400fd43d

add http/jetty
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 29 Jan 2018 17:50:49 -0700
parents src/luan/modules/http/LuanHandler.java@e15be31cee92
children
comparison
equal deleted inserted replaced
1135:707a5d874f3e 1136:d30d400fd43d
1 package luan.modules.http.jetty;
2
3 import java.io.IOException;
4 import java.lang.reflect.Method;
5 import java.net.BindException;
6 import java.util.concurrent.locks.ReadWriteLock;
7 import java.util.concurrent.locks.ReentrantReadWriteLock;
8 import javax.servlet.http.HttpServletRequest;
9 import javax.servlet.http.HttpServletResponse;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 import org.eclipse.jetty.server.Request;
13 import org.eclipse.jetty.server.Server;
14 import org.eclipse.jetty.server.handler.AbstractHandler;
15 import luan.Luan;
16 import luan.LuanState;
17 import luan.LuanTable;
18 import luan.LuanFunction;
19 import luan.LuanJavaFunction;
20 import luan.LuanCloner;
21 import luan.LuanException;
22 import luan.modules.PackageLuan;
23
24
25 public class LuanHandler extends AbstractHandler {
26 private final LuanState luanInit;
27 private final Logger logger;
28 private String welcomeFile = "index.html";
29 private final ReadWriteLock lock = new ReentrantReadWriteLock();
30 private LuanState luan;
31
32 private static final Method resetLuanMethod;
33 static {
34 try {
35 resetLuanMethod = LuanHandler.class.getMethod("reset_luan");
36 } catch(NoSuchMethodException e) {
37 throw new RuntimeException(e);
38 }
39 }
40
41 public LuanHandler(LuanState luan,String loggerRoot) {
42 this.luanInit = luan;
43 if( loggerRoot==null )
44 loggerRoot = "";
45 logger = LoggerFactory.getLogger(loggerRoot+LuanHandler.class.getName());
46 try {
47 LuanTable Http = (LuanTable)PackageLuan.require(luanInit,"luan:http/Http.luan");
48 Http.rawPut( "reset_luan", new LuanJavaFunction(resetLuanMethod,this) );
49 } catch(LuanException e) {
50 throw new RuntimeException(e);
51 }
52 }
53
54 @Override public void handle(String target,Request baseRequest,HttpServletRequest request,HttpServletResponse response)
55 throws IOException
56 {
57 if( target.endsWith("/") )
58 target += welcomeFile;
59 Thread thread = Thread.currentThread();
60 String oldName = thread.getName();
61 thread.setName(request.getHeader("host")+request.getRequestURI());
62 lock.readLock().lock();
63 try {
64 if( !HttpServicer.service(luan,request,response,"site:"+target+".luan") )
65 return;
66 } catch(LuanException e) {
67 //e.printStackTrace();
68 String err = e.getLuanStackTraceString();
69 logger.error(err);
70 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,err);
71 } finally {
72 lock.readLock().unlock();
73 thread.setName(oldName);
74 }
75 baseRequest.setHandled(true);
76 }
77
78 public void setWelcomeFile(String welcomeFile) {
79 this.welcomeFile = welcomeFile;
80 }
81
82 @Override protected void doStart() throws Exception {
83 // Thread.dumpStack();
84 //System.out.println("qqqqqqqqqqqqqqqqqqqq doStart "+this);
85 setLuan();
86 super.doStart();
87 }
88
89 @Override protected void doStop() throws Exception {
90 synchronized(luan) {
91 luan.close();
92 }
93 //System.out.println("qqqqqqqqqqqqqqqqqqqq doStop "+this);
94 super.doStop();
95 }
96 /*
97 @Override public void destroy() {
98 System.out.println("qqqqqqqqqqqqqqqqqqqq destroy "+this);
99 super.destroy();
100 }
101 */
102
103 public Object call_rpc(String fnName,Object... args) throws LuanException {
104 lock.readLock().lock();
105 try {
106 LuanFunction fn;
107 LuanState luan = this.luan;
108 synchronized(luan) {
109 PackageLuan.enableLoad(luan,"luan:Rpc.luan");
110 LuanTable rpc = (LuanTable)PackageLuan.require(luan,"luan:Rpc.luan");
111 LuanTable fns = (LuanTable)rpc.get(luan,"functions");
112 fn = (LuanFunction)fns.get(luan,fnName);
113 if( fn == null )
114 throw new LuanException( "function not found: " + fnName );
115 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL);
116 luan = (LuanState)cloner.clone(luan);
117 fn = (LuanFunction)cloner.get(fn);
118 }
119 return fn.call(luan,args);
120 } finally {
121 lock.readLock().unlock();
122 }
123 }
124
125 public void reset_luan() {
126 new Thread() {
127 public void run() {
128 lock.writeLock().lock();
129 try {
130 synchronized(luan) {
131 luan.close();
132 setLuan();
133 }
134 } catch(IOException e) {
135 logger.error("reset_luan failed",e);
136 } finally {
137 lock.writeLock().unlock();
138 }
139 }
140 }.start();
141 }
142
143 private void setLuan() {
144 LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
145 luan = (LuanState)cloner.clone(luanInit);
146 try {
147 PackageLuan.load(luan,"site:/init.luan");
148 } catch(LuanException e) {
149 String err = e.getLuanStackTraceString();
150 logger.error(err);
151 }
152 }
153
154 public Object runLuan(String sourceText,String sourceName) throws LuanException {
155 LuanFunction fn = Luan.load(sourceText,sourceName);
156 synchronized(luan) {
157 LuanCloner cloner = new LuanCloner(LuanCloner.Type.INCREMENTAL);
158 LuanState luan = (LuanState)cloner.clone(this.luan);
159 return fn.call(luan);
160 }
161 }
162
163 public static void start(Server server) throws Exception {
164 try {
165 server.start();
166 } catch(BindException e) {
167 throw new LuanException(e.toString());
168 }
169 }
170
171 }