我正在使用Akka,并希望为所有情况下的一个PartialFunction运行一些代码。对于演员监督,我有这样的东西:
val supervisorStrategy = OneForOneStrategy() {
case npe: NullPointerException => Stop
case re: RuntimeException => Restart
}
我发现在所有情况下运行一些代码而不必在每个情况下重新编写的唯一方法是:
val pf = new PartialFunction[Throwable, Directive] {
def apply(throwable: Throwable) = {
doSomething(throwable)
throwable match {
case NullPointerException => Stop
case RuntimeException => Restart
}
}
def isDefinedAt(throwable: Throwable) = true
}
val supervisorStrategy = OneForOneStrategy()(pf)
我已经四处寻找了其他的答案(比如这个),但无法找到任何替代我想到的方法。
似乎不是阿卡特有的。你可以用andThen
组合任意两个函数。具体来说:
package com.example
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy.{Decider, Restart, Stop}
object Answer extends App {
val doSomething:PartialFunction[Throwable, Throwable] = { case e =>
println(s"doing something with $e")
e
}
val decide:Decider = {
case _:NullPointerException => Stop
case _:RuntimeException => Restart
}
val strategy = OneForOneStrategy()(doSomething andThen decide)
val errors = Seq(new NullPointerException, new RuntimeException)
errors map strategy.decider foreach println
}
一般:
package com.example
object Answer extends App {
val inspect:PartialFunction[Throwable, Throwable] = { case e =>
println(s"inspecting $e")
e
}
val decide:PartialFunction[Throwable, String] = {
case npe:NullPointerException => "NPE!"
case iae:IllegalArgumentException => "Bad arg!"
}
val combined = inspect andThen decide
val errors = Seq(new NullPointerException, new IllegalArgumentException)
errors map combined foreach println
}
应该这样做:
val supervisorStrategy = OneForOneStrategy() {
case x =>
doSomething(x)
x match {
case npe: NullPointerException => Stop
case re: RuntimeException => Restart
}
}
感谢您的其他答案,但是在这个Akka特定的情况下,我无法让它们工作。例如,这不会编译:
val ft = OneForOneStrategy() { x: Throwable =>
doSomething(x)
x match {
case npe: NullPointerException => Stop
case re: RuntimeException => Stop
}
}
Error:(48, 47) type mismatch;
found : Throwable => akka.actor.SupervisorStrategy.Directive
required: akka.actor.SupervisorStrategy.Decider (which expands to) PartialFunction[Throwable,akka.actor.SupervisorStrategy.Directive]
我正在使用Akka 2.4.11和Scala 2.11.8
对我来说唯一有效的解决方案是我在最初的问题中描述的方法。