patorashのブログ

方向性はまだない

grinderを使ってpub serveとサーバサイドの起動を同時に行う

前回の記事では、サーバサイドにアクセスしたら特定の条件によってpub serveで起動しているサーバを中継してdartやjsやcssのファイルを返すようにしました。今度は、この2つのサーバを同時に立ち上げたいなと思ったのでやってみることにしました。grinderを使うと簡単にできました。grinderの関数のrunAsyncを使います。

@DefaultTask()
@Depends(compile)
serve() async {
  runAsync('pub', arguments: ['serve', 'web/client', '--port=8000']);
  Process process = await getStreamProcess();
  stdout.addStream(process.stdout);
  stderr.addStream(process.stderr);

  // rspファイルの変更を検知してコンパイルする
  var clientWatcher = new DirectoryWatcher(path.absolute('web/client'));
  clientWatcher.events.listen((event) async {
    if (event.path.endsWith('.rsp.html')) {
      runAsync('dart', arguments: ['build.dart']);
    }
  });

  var serverWatcher = new DirectoryWatcher(path.absolute('web/webapp'));
  serverWatcher.events.listen((event) async {
    if (event.path.endsWith('.dart')) {
      log("Server: file change detected.");
      // ファイルのコンパイル後にrekulo streamを再起動させる
      log("Server: kill process...");
      if (process.kill(ProcessSignal.SIGTERM)) {
        process = await getStreamProcess();
        log("Server: restart done.");
      }
    }
  });
}

自分でpub serveを行うProcessを立ち上げてもいいのですが、それを行うと標準出力・エラー出力の周辺の取り回しが面倒なので、runAsyncに任せたほうが楽そうでした。でもrunAsyncを使うと、戻り値がProcessではないので、pub serveのような終わらない処理を終了させるにはCtrl + Cしかありません。まぁ今回はそれでよかったので、このままいこうと思います。