在Play 2.6中,我在控制器中使用以下代码来启动WebSocket actor:
def ws: WebSocket = WebSocket.accept[JsValue, JsValue] { request =>
ActorFlow.actorRef { out =>
WebSocketActor.props(request.id.toString, out)
}
}
Internally Play将创建一个接收器演员,我的演员(WebSocketActor
)将被创建为该演员的孩子。接收器actor提供了一些默认监督策略(错误Stop
),但我想设置自己的策略,以便在发生故障时重新启动WebSocketActor
。我该怎么办?
答案 0 :(得分:0)
播放ActorFlow
并没有提供一种方法来覆盖其主管策略,即在抛出异常时停止您的actor。但是,您可以使用您选择的策略定义自己的ActorFlow
副本:
import akka.actor._
import akka.stream.{ Materializer, OverflowStrategy }
import akka.stream.scaladsl.{ Sink, Keep, Source, Flow }
object ActorFlowAlt {
def actorRef[In, Out](props: ActorRef => Props, bufferSize: Int = 16, overflowStrategy: OverflowStrategy = OverflowStrategy.dropNew)(implicit factory: ActorRefFactory, mat: Materializer): Flow[In, Out, _] = {
val (outActor, publisher) = Source.actorRef[Out](bufferSize, overflowStrategy)
.toMat(Sink.asPublisher(false))(Keep.both).run()
Flow.fromSinkAndSource(
Sink.actorRef(factory.actorOf(Props(new Actor {
val flowActor = context.watch(context.actorOf(props(outActor), "flowActor"))
def receive = {
case Status.Success(_) | Status.Failure(_) => flowActor ! PoisonPill
case Terminated(_) => context.stop(self)
case other => flowActor ! other
}
override def supervisorStrategy = OneForOneStrategy() {
case _ => SupervisorStrategy.Restart // <--- restart instead of stop
}
})), Status.Success(())),
Source.fromPublisher(publisher)
)
}
}
然后在您的控制器中使用此替代方案:
def ws: WebSocket = WebSocket.accept[JsValue, JsValue] { request =>
ActorFlowAlt.actorRef { out =>
WebSocketActor.props(request.id.toString, out)
}
}