【问题标题】:How to set supervision strategy for websocket actor in Play Framework?如何在 Play Framework 中为 websocket actor 设置监督策略?
【发布时间】:2017-10-18 15:26:28
【问题描述】:

在 Play 2.6 中,我在控制器中使用以下代码来启动 WebSocket 演员:

def ws: WebSocket = WebSocket.accept[JsValue, JsValue] { request =>
  ActorFlow.actorRef { out =>
      WebSocketActor.props(request.id.toString, out)
  }
}

Internally Play 将创建一些接收器 Actor,我的 Actor (WebSocketActor) 将创建为该 Actor 的子代。接收器参与者提供了一些默认的监督策略(Stop 出错),但我想设置自己的策略以在失败时重新启动 WebSocketActor。我该怎么做?

【问题讨论】:

    标签: scala playframework websocket akka


    【解决方案1】:

    Play 的ActorFlow 没有提供一种方法来覆盖其主管策略,即在引发异常时停止您的演员。但是,您可以使用您选择的策略简单地定义自己的 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)
      }
    }
    

    【讨论】:

    • 谢谢。我也想过,但我在想可能有更好的方法。
    猜你喜欢
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 2021-11-24
    • 2013-01-14
    • 2018-07-17
    • 2018-03-17
    相关资源
    最近更新 更多