start method

Future start ({int numberOfInstances: 1, bool runOnMainIsolate: false, bool consoleLogging: false })

Starts the application by spawning Isolates that listen for HTTP requests.

Returns a Future that completes when all Isolates have started listening for requests. The numberOfInstances defines how many Isolates are spawned running this application's configuration and RequestSinkType. If runOnMainIsolate is true (it defaults to false), the application will run a single instance of RequestSinkType on the main isolate, ignoring numberOfInstances. Additionally, the server will only listen on localhost, regardless of any specified address. You should only runOnMainIsolate for testing purposes.

If this instances RequestSinkType implements initializeApplication (see RequestSink for more details), that one-time initialization method will be executed prior to the spawning of isolates and instantiations of RequestSink.

Implementation

Future start(
    {int numberOfInstances: 1,
    bool runOnMainIsolate: false,
    bool consoleLogging: false}) async {
  if (server != null || supervisors.length > 0) {
    throw new ApplicationStartupException("Application already started.");
  }

  if (configuration.address == null) {
    if (runOnMainIsolate) {
      configuration.address = InternetAddress.LOOPBACK_IP_V4;
    } else {
      if (configuration.isIpv6Only) {
        configuration.address = InternetAddress.ANY_IP_V6;
      } else {
        configuration.address = InternetAddress.ANY_IP_V4;
      }
    }
  }

  var requestSinkType = reflectClass(RequestSinkType);
  await _globalStart(requestSinkType, configuration);

  if (runOnMainIsolate) {
    if (numberOfInstances > 1) {
      logger.info(
          "runOnMainIsolate set to true, ignoring numberOfInstances (set to $numberOfInstances)");
    }

    try {
      var sink = requestSinkType
          .newInstance(new Symbol(""), [configuration]).reflectee;
      server = new ApplicationServer(configuration, 1, captureStack: true);

      await server.start(sink);
    } catch (e, st) {
      logger.severe("$e", this, st);
      await stop().timeout(new Duration(seconds: 5));
      throw new ApplicationStartupException(e);
    }
  } else {
    try {
      for (int i = 0; i < numberOfInstances; i++) {
        var supervisor =
            await _spawn(configuration, i + 1, logToConsole: consoleLogging);
        supervisors.add(supervisor);
        await supervisor.resume();
      }
    } catch (e, st) {
      logger.severe("$e", this, st);
      await stop().timeout(new Duration(seconds: 5));
      rethrow;
    }
    supervisors.forEach((sup) => sup.sendPendingMessages());
  }

  _interruptSubscription = ProcessSignal.SIGINT.watch().listen((evt) {
    logger.info("Shutting down due to interrupt signal.");
    stop();
  });
}