I've been modifying some sample code to use for a web server, this way I can have dart running on both the server and the client. However, I decided I wanted to check out the performance of the web server, and I'm mostly impressed, except for the crashing. I'm using the "siege" package on Ubuntu to generate lots of traffic to the website using a handful of URLs.
I've seen it delivering a little north of 1000 transactions per second, which is very acceptable for me, but after two to three minutes run time it either crashes or hangs (if I increase the new_gen_heap_size).
#import('dart:io');
class FCServer {
String basePath;
void send404(HttpResponse response)
{
response.statusCode = HttpStatus.NOT_FOUND;
response.outputStream.close();
}
void handleRequest(HttpRequest request, HttpResponse response)
{
final String path = request.path == '/' ? '/index.html' : request.path;
final File file = new File('${basePath}${path}');
file.exists().then((bool found) {
if (found)
{
file.fullPath().then((String fullPath) {
if (!fullPath.startsWith(basePath))
{
send404(response);
}
else
{
//print("delivering $fullPath");
response.headers.add("Cache-Control", "max-age=3600");
//file.openInputStream().pipe(response.outputStream);
var file = new File("$fullPath");
//response.headers.set(HttpHeaders.CONTENT_TYPE, "$contentType; charset=UTF-8");
response.outputStream.write(file.readAsBytesSync());
response.outputStream.close();
}
});
}
else
{
send404(response);
}
});
}
void startServer(String basePath)
{
this.basePath = basePath;
var server = new HttpServer();
print("Starting server with basePath: $basePath");
server.listen('192.168.0.14', 8080);
server.listen('127.0.0.1', 8080);
server.defaultRequestHandler = handleRequest;
}
}
FCServer webServe;
main()
{
// Compute base path for the request based on the location of the
// script and then start the server.
webServe = new FCServer();
File script = new File(new Options().script);
script.directory().then((Directory d) {
webServe.startServer(d.path);
});
}
The error that Dart prints before exiting is as follows:
Exhausted heap space, trying to allocate 128096 bytes.
Exhausted heap space, trying to allocate 112 bytes.
Exception 'Instance of 'OutOfMemoryException'' thrown:
Exiting the process
Does this mean that there is a memory leak somewhere? Or can someone explain what is going on?
EDIT: when the new_gen_heap_size is increased to 1024, it does hang after awhile and a single thread sits at 100% whether requests are incoming or not. At this point the RAM is up to 1.5GB after a run through with the aforementioned heap size, so I assume the garbage collector has kicked the bucket, so to speak.
EDIT 2: I've modified the code so that on initialization it creates a List consisting of 4 bytes, then every time a request is made it simply writes that List to the response and closes the response. The memory usage still grows rapidly, indicating a problem deeper within Dart. This makes me weary of using Dart for a full scale project.