2017-10-18 42 views
0

En jeu 2.6 J'utilise le code suivant dans mon contrôleur pour faire tourner un acteur WebSocket:Comment définir la stratégie de supervision de l'acteur websocket dans Play Framework?

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

interne Jouez va créer un acteur de puits et mon acteur (WebSocketActor) est créé comme un enfant de cette acteur. L'acteur de puits fournit une stratégie de supervision par défaut (Stop en cas d'erreur), mais je voudrais définir ma propre stratégie pour redémarrer WebSocketActor en cas d'échec. Comment puis-je le faire?

Répondre

0

Le jeu ActorFlow de Play ne permet pas de contourner sa stratégie de superviseur consistant à arrêter votre acteur lorsqu'une exception est levée. Vous pouvez cependant définir simplement votre propre copie de ActorFlow avec la stratégie de votre choix:

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) 
    ) 
    } 
} 

Ensuite, utilisez cette option dans votre contrôleur:

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

Merci. J'y ai aussi réfléchi mais je pensais qu'il y aurait peut-être une meilleure façon de le faire. – Piotr