Search code examples
asynchronouswebserverdartblocking

Is it a bad idea to use synchronous filesystem methods in a Dart web server?


I'm playing around with HttpServer; and was adding support for serving static files (I'm aware of Shelf; I'm doing this as a learning exercise). I have a list of handlers that are given the opportunity to handle the request in sequence (stopping at the first that handles it):

const handlers = const [
  handleStaticRequest
];

handleRequest(HttpRequest request) {
  // Run through all handlers; and if none handle the request, 404
  if (!handlers.any((h) => h(request))) {
    request.response.statusCode = HttpStatus.NOT_FOUND;
    request.response.headers.contentType = new ContentType("text", "html");
    request.response.write('<h1>404 File Not Found</h1>');
    request.response.close();
  }
}

However, as I implemented the static file handler, I realised that I couldn't return true/false directly (which is required by the handleRequest code above, to signal if the request is handled) unless I use file.existsSync().

In something like ASP.NET, I wouldn't think twice about a blocking call in a request because it's threaded; however in Dart, it seems like it would be a bottleneck if every request is blocking every other request for the duration of IO hits like this.

So, I decided to have a look in Shelf, to see how that handled this; but disappointingly, that appears to do the same (in fact, it does several synchronous filesystem hits).

Am I overestimating the impact of this; or is this a bad idea for a Dart web service? I'm not writing Facebook; but I'd still like to learn to write things in the most efficient way.

If this is considered bad; is there a built-in way of doing "execute these futures sequentially until the first one returns a match for this condition"? I can see Future.forEach but that doesn't have the ability to bail. I guess "Future.any" is probably what it'd be called if it existed (but that doesn't)?


Solution

  • There are a lot of good questions in your post (perhaps we should split them out into individual SO questions?).

    To answer the post title's question, the best practice for servers is to use the async methods.

    For command-line utilities and simple scripts, the sync methods are perfectly fine.