Given 是一个基于 Spring MVC 的 Webapp,它执行接收到的客户端源代码(用 java 编写)并返回它的输出。
在 jsp 中,我有一个 jquery 函数,它通过以下方式将客户端代码发送到服务器:
$.post(contextPath('/submit/run'), {
className: className, // somewhere blah blah
source: code,
args: args,
stdin: stdin
}, function(data) {
log(data);
});
收到:
@RequestMapping(value = "/run", method = RequestMethod.POST)
public @ResponseBody String run(@RequestParam("className") String className,
@RequestParam("source") String source,
@RequestParam("args") String args,
@RequestParam("stdin") String stdin){
final CodeRunner runner = ...; // Compiles, Executes..
return runner.run(); // Then returns output from StdOut
}
一切正常,但是。运行器可以在定义的时间内执行代码,即:如果超过n
秒则杀死线程。但是,如果客户端代码执行带有循环的代码,<~n sec
例如:
for(int i = 0; i < 200000; i++)
System.out.println("Not so infinite loop.");// runs 0.87 second, but prints a lot
浏览器滞后,因为它似乎在等待响应。
我最初认为,也许我将输出附加到运行器内的字符串生成器的方式是一个循环。所以我改变了这个:
String line;
while((line = reader.readline()) != null){
output.append(line).append("\r\n"); // output = StringBuilder, reader = BufferedReader
}
对此,正如我在这里看到的:
output.append(IOUtils.toString(proc.getInputStream(), "UTF-8"));
浏览器从滞后中恢复得更快。
显然,还是不够。如果允许代码在 中运行n=5 seconds
,并且在 中执行<n seconds
,那么浏览器也会滞后<n seconds
。
问题:我可以使用什么方法来规避这个问题?我正在考虑部分发送输出块,以便页面立即收到响应,其余的输出将随之而来。如果这是一个好方法,我该如何在 jquery 和 spring 控制器中进行配置?
或者更重要的是,有没有更好的方法?
PS:我确信 InputStream 的附加是问题,因为注释掉行会消除滞后。