Cómo convertir un clásico ActorContext a uno tipo

Digamos que defino algunos mensajes:

sealed trait Command
case class A(i: Int) extends Command
case class B(str: String) extends Command

Y luego un actor clásico como abajo para manejar estos mensajes. En la creación necesito acceso al ActorContext pero como un contexto tipo no un clásico

class MyActor extends Actor {

  val typedContext: ActorContext[Command] = ???

  def receive = {
    case A(i) =>
      // Do something with i
    case B(str)
     // Do something with str

  }
}

Sé que puedo hacer auto.para escribir [Command] para obtener la referencia automática tipo. Pero no puedo encontrar nada similar para el ActorContext. ¿Cómo iba a ir acerca de la conversión?

Pregunta hecha hace 3 años, 4 meses, 29 días - Por techinnovator


3 Respuestas:

  • No hay conversión de un clásico ActorContext a un tipo ActorContext. Sobre las únicas cosas que se escriben ActorContext puede hacer eso un clásico ActorContext No puede ser:

    • pregunte a otro actor y adapte el resultado (para hacer eso en el clásico, utiliza el patrón de pregunta clásico: import akka.pattern.ask)
    • un futuro para el actor (para eso import akka.pattern.pipe)
    • tomar ventaja del ciclo de vida de un actor tipo (spawn, watch, unwatch, stop)

    Para el último, puedes

    import akka.actor.typed.scaladsl.adapter.ClassicActorContextOps
    

    que añadirá

    • spawn/spawnAnonymous
    • watch
    • unwatch
    • stop

    métodos que manejan tipo.

    Respondida el Dec 16, 2020 a las 20:44 - por csscraftsman

    Votos positivos: 0 | Votos negativos: 0

  • Para convertir un ActorContext clásico a uno tipo en Akka Typed, puedes usar la clase Adapter. Aquí te muestro cómo se puede realizar esa conversión en tu código:

    • Define un objeto compañero en tu clase MyActor para contener la conversión de ActorContext clásico a uno tipo:
    scala
    object MyActor {
      def apply(): Behavior[Command] = {
        Behaviors.setup(context => new MyActor(context).behavior)
      }
    }
    
    • Modifica la definición de MyActor para aceptar un ActorContext clásico y lo convierte a uno tipo:
    scala
    class MyActor(context: ActorContext[Command]) {
    
      def behavior: Behavior[Command] = {
        Behaviors.receiveMessage {
          case A(i) =>
            // Do something with i
            Behaviors.same
    
          case B(str) =>
            // Do something with str
            Behaviors.same
        }
      }
    
    }
    
    • Finalmente, utiliza el objeto compañero para crear una instancia de MyActor y obtener el comportamiento como un `Behavior[Command]`:
    scala
    val myActorBehavior: Behavior[Command] = MyActor()
    val myActorRef = ActorSystem(myActorBehavior, "myActor")
    

    Con estos cambios, has convertido la definición clásica de un Actor en Akka a una versión tipo compatible con Akka Typed, y podrás manejar los mensajes definidos en tu trait Command de manera segura en un entorno tipado.

    Respondida el Dec 17, 2020 a las 20:44 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Para convertir un ActorContext clásico a un Context de tipo, puedes utilizar el método typed:

    scala
    val typedContext: Context[Command] = context.typed[Command]
    

    Esto creará un nuevo Context de tipo que está respaldado por el ActorContext clásico. El Context de tipo proporcionará acceso a los mismos métodos y funcionalidades que el ActorContext clásico, pero con tipos estáticos para los mensajes.

    Aquí tienes un ejemplo actualizado de tu código que utiliza un Context de tipo:

    scala
    class MyActor extends Actor {
    
      val context: Context[Command] = context.typed[Command]
    
      def receive = {
        case A(i) =>
          // Do something with i
        case B(str) =>
          // Do something with str
      }
    }
    

    Ten en cuenta que el método typed solo está disponible en Akka >= 2.5.0. Si estás utilizando una versión anterior de Akka, puedes utilizar el siguiente código para convertir un ActorContext clásico a un Context de tipo:

    scala
    import akka.actor.typed.scaladsl.adapter._
    val typedContext: Context[Command] = context.toScalaTyped[Command]
    

    Este código creará un Context de tipo que está adaptado del ActorContext clásico. El Context de tipo adaptado proporcionará acceso a los mismos métodos y funcionalidades que el ActorContext clásico, pero con tipos estáticos para los mensajes.

    Respondida el Dec 17, 2020 a las 20:46 - por Gemini

    Votos positivos: 0 | Votos negativos: 0