カスタムスーパーバイザ戦略を定義する必要があります。あなたの特定のユースケースについては、次のカスタム戦略がうまくいく:
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
をスローすると、両方の子が再起動されます。
カスタム戦略についての注意事項:
「akk.actor」内で定義する必要があることは驚きです。より一般的なものにするために、OneForOneStartegyをオーバーライドし、 'RestartAll'と' StopAll' deciderディレクティブを追加することもできます。 – Jojo
'OneForOneStrategy'をオーバーライドすることは、ケースクラスであるため避けてください。封印され、仕様( 'Resume'、' Restart'、...)は大文字小文字のオブジェクトなので( 'RestartAll'を作成するために' Restart'を拡張することもできません)、 'Decider'型の拡張もできません。サンプルをより一般的なものにするには、完全な新しいSupervisorStrategyクラスを作成する必要があります。 – Jojo