7

長時間の作業には、スレッドセーフな(不変の)Scalaクラスが必要です。一部のコーナーケースでは、タスクに非常に時間がかかるため、タイムアウトを実装したいと思います。これを不変のクラスに実装するための最良の方法は何ですか?

私の最初の試みは、次のような暗黙のパラメーターを使用することでした。

class Worker(val input: String) {

  def start: String = {
    implicit val startTimeStamp = new TimeStamp
    doSomething1 + doSomething2
  }

  def doSomething1()(implicit startTimeStamp: TimeStamp): String = { ... }

  def doSomething2()(implicit startTimeStamp: TimeStamp): String = {
    ... 
    checkTimeout 
    ...
   }
}

class TimeStamp { val start = System.currentTimeMillis }

これは機能するはずですが、暗黙のパラメーターを持つボイラープレートコードがまだたくさんあります。doSomething(実際のコードでは、workerクラスに何百もの深くネストされた関数があります。)Scalaでこれを行うためのより美しい方法はありますか?

4

2 に答える 2

5

先物を探しているようですね。scala 2.9.xでは、そのためにakkaライブラリを使用することをお勧めします。2.10.0以降にはscala.concurrent.Future特性があります。

2.10の例:

import concurrent._
import concurrent.duration._
import ExecutionContext.Implicits.global

val f = future {
  blocking {
    // long running task
  }
}

try {
  val res = Await.result(f, 100 millis)
} catch {
  case e: java.util.concurrent.TimeoutException =>
    // handle timeout
}

編集:blocking ViktorKlangによって提案された呼び出しを追加しました。

于 2013-02-04T16:24:56.260 に答える
3

Hystrixを使用します。それはあなたが求めていることを正確に実行するJavaライブラリです。Scalaとうまく連携し、優れたドキュメントを入手しました。

例:

class LongOperation(...) extends HystrixCommand[Result](
  HystrixCommandProperties.Setter()
    .withExecutionIsolationThreadTimeoutInMilliseconds(60 * 1000))
{
  override protected def run: Result = {
    // your code
  }
}

同期して実行する方法:

val result = new LongOperation(...).execute()
于 2013-02-04T16:10:04.550 に答える