dartdart-iodart-isolates

How to use multiple isolates to serve requests


How can a Dart server be set up to use all available cores for in coming requests (e.g. by using multiple isolates to serve requests)?


Solution

  • Use the shared: true argument of HttpServer.bind. Example:

    import 'dart:io';
    import 'dart:isolate';
    
    import 'package:shelf/shelf.dart' as shelf;
    import 'package:shelf/shelf_io.dart' as shelf_io;
    import 'package:args/args.dart' show ArgParser;
    
    main(List<String> args) {
       var parser = new ArgParser()
       ..addOption('address', abbr: 'a', defaultsTo: '0.0.0.0')
       ..addOption('port', abbr: 'p', defaultsTo: '9393')
       ..addOption('isolates', abbr: 'i', defaultsTo: '3');
       var arguments = parser.parse(args);
    
       var nbOfIsolates = int.parse(arguments['isolates']);
       for (int i = 1; i < nbOfIsolates; i++) {
          Isolate.spawn(_startShelfServer, [arguments['address'], int.parse(arguments['port'])]);
       }
       _startShelfServer([arguments['address'], int.parse(arguments['port'])]);
    }
    
    _startShelfServer(List args) async {
       String address = args[0];
       int port = args[1];
    
       var helloWorldHandler = (shelf.Request request) => new shelf.Response.ok("Hello World - from isolate ${Isolate.current.hashCode}");  
       var handler = const shelf.Pipeline()
       .addHandler(helloWorldHandler);
       var server = await HttpServer.bind(address, port, shared: true);
       await shelf_io.serveRequests(server, handler);
       print('Serving at http://${server.address.host}:${server.port} - isolate: ${Isolate.current.hashCode}');    
    }