2017-07-06 21 views
3

私がOneForOneStrategyAllForOneStrategyの両方を使用するにはどうすればScalaのアクタのスーパーバイザ戦略を定義できますか?それらを組み合わせる簡単な方法はありますか?またはカスタムを定義する必要がありますかSupervisorStrategyAkka:OneForOneStrategyとAllForOneStrategyを組み合わせる方法

class MyActor extends Actor { 
    override val supervisorStrategy = OneForOneStrategy() { 
    case _: NullPointerException => Restart 
    case _: FileNotFoundException => Restart // here I want to restart all children 
    case _: Exception    => Escalate 
    } 
} 

私は自分の上司の戦略を記述する必要がある場合、私はこれをどのように行うことができます。 ここでは一例ですか?私はその事例を見つけませんでした。

答えて

0

カスタムスーパーバイザ戦略を定義する必要があります。あなたの特定のユースケースについては、次のカスタム戦略がうまくいく:

package akka.actor 

import java.io.FileNotFoundException 
import scala.concurrent.duration._ 

case class CustomStrategy(
    maxNrOfRetries:    Int  = -1, 
    withinTimeRange:    Duration = Duration.Inf, 
    override val loggingEnabled: Boolean = true)(val decider: SupervisorStrategy.Decider) 
    extends SupervisorStrategy { 

    import SupervisorStrategy._ 

    private val retriesWindow = (maxNrOfRetriesOption(maxNrOfRetries), withinTimeRangeOption(withinTimeRange).map(_.toMillis.toInt)) 

    def handleChildTerminated(context: ActorContext, child: ActorRef, children: Iterable[ActorRef]): Unit =() 

    def processFailure(context: ActorContext, restart: Boolean, child: ActorRef, cause: Throwable, stats: ChildRestartStats, children: Iterable[ChildRestartStats]): Unit = { 
    if (cause.isInstanceOf[FileNotFoundException]) { 
     // behave like AllForOneStrategy 
     if (children.nonEmpty) { 
     if (restart && children.forall(_.requestRestartPermission(retriesWindow))) 
      children foreach (crs ⇒ restartChild(crs.child, cause, suspendFirst = (crs.child != child))) 
     else 
      for (c ← children) context.stop(c.child) 
     } 
    } else { 
     // behave like OneForOneStrategy 
     if (restart && stats.requestRestartPermission(retriesWindow)) 
     restartChild(child, cause, suspendFirst = false) 
     else 
     context.stop(child) 
    } 
    } 
} 

Hereは、上記の戦略をテスト要旨です。この仕様では、CustomStrategyを使用するスーパーバイザが作成され、2人の子が作成されます。 1人の子がNullPointerExceptionを投げた場合、その子だけが再起動されます。子がFileNotFoundExceptionをスローすると、両方の子が再起動されます。

カスタム戦略についての注意事項:

  • それはSupervisorStrategyを拡張し、既存の戦略はhereを定義した後にモデル化されます。
  • akka.actorパッケージ内で定義されており、そこにパッケージプライベートメンバーへのアクセス権があります。
  • processFailureのように、SupervisorStrategyに拡張されたクラスでオーバーライドする必要があるメソッドの1つは、RestartStopで呼び出されるため、ここではカスタムビヘイビアを定義します。
+0

「akk.actor」内で定義する必要があることは驚きです。より一般的なものにするために、OneForOneStartegyをオーバーライドし、 'RestartAll'と' StopAll' deciderディレクティブを追加することもできます。 – Jojo

+0

'OneForOneStrategy'をオーバーライドすることは、ケースクラスであるため避けてください。封印され、仕様( 'Resume'、' Restart'、...)は大文字小文字のオブジェクトなので( 'RestartAll'を作成するために' Restart'を拡張することもできません)、 'Decider'型の拡張もできません。サンプルをより一般的なものにするには、完全な新しいSupervisorStrategyクラスを作成する必要があります。 – Jojo

関連する問題