MBAで実行しているときは一度も起きなかったんだけど、メイン機(Win/Linux両方)でscala.sys.process.ProcessBuilderからmecabを実行すると、ときたま帰ってこなかったりする。大量に処理しようとするとこれでは困るので、タイムアウトとリトライ処理を実装してみた。

@tailrec
def retry(pb: ProcessBuilder, count: Int = 0)(implicit timeout: FiniteDuration): String = {
  lazy val out = new StringBuilder
  val p = pb.run(ProcessLogger(x => out.append(x), System.err.print))
  try {
    Await.result(Future.apply(blocking(p.exitValue)), timeout)
    out.toString
  } catch {
    case e: TimeoutException =>
      p.destroy()
      if (count > 0)
        retry(pb, count - 1)
      else
        throw e
  }
}

タイムアウト時間はscala.concurrent.duration.FiniteDurationを利用して指定する。また、Futureを利用するので、globalをimportするか、適切なExecutionContextを作成する必要がある。


参考