comparison src/luan/modules/http/impl/LuanHandler.java @ 1160:4beabb087be6

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