Search code examples
scalazio

Creating two actors performing basic ping-pong communication using ZIO Actors


I'm newbie to Actors and trying to perform simple ping pong example using type hierarchy and Stateful instance. I followed exactly zio actors [micro-site][1] with a little update on the program code. My configuration file at ./src/main/resources/application.conf looks as below :

testSystemOne.zio.actors.remoting {
  hostname = "127.0.0.1"
  port = 8055
}
testSystemTwo.zio.actors.remoting {
  hostname = "127.0.0.1"
  port = 8056
}

And MyApp.scala :

import zio.actors.Actor.Stateful
import zio.actors._
import zio.RIO
import zio.console._

object MyApp extends zio.App {

  sealed trait PingPong[+_]
  case class Ping(sender: ActorRef[PingPong]) extends PingPong[Unit]
  case object Pong extends PingPong[Unit]
  case class GameInit(recipient: ActorRef[PingPong]) extends PingPong[Unit]

  def run(args: List[String]) =
    program.exitCode

  val protoHandler = new Stateful[Console, Unit, PingPong] {
    override def receive[A](state: Unit, msg: PingPong[A], context: Context): RIO[Console, (Unit, A)] =
      msg match {
        case Ping(sender) =>
          for {
            _ <- putStrLn("Ping!")
            path <- sender.path
            _ <- sender ! Pong
          } yield ((), ())

        case Pong =>
          for {
            _ <- putStrLn("Pong!")
          } yield ((), ())

        case GameInit(to) =>
          for {
            self <- context.self[PingPong]
            _ <- to ! Ping(self)
          } yield ((), ())
      }
  }

  val program = for {
    actorSystemRoot <- ActorSystem("testSystemOne")
    one <- actorSystemRoot.make("actorOne", Supervisor.none, (), protoHandler)

    actorSystem <- ActorSystem("testSystemTwo")
    _ <- actorSystem.make("actorTwo", Supervisor.none, (), protoHandler)

    remoteActor <- actorSystemRoot.select[PingPong](
      "zio://[email protected]:8056/actorTwo"
    )

    _ <- one ! GameInit(remoteActor)

  } yield ()

}

I'm not sure if I update the code correctly , this is what I got when I run the code

Fiber failed.
An unchecked error was produced.
java.lang.ClassCastException: class zio.ZRef$Atomic cannot be cast to class zio.Ref (zio.ZRef$Atomic and zio.Ref are in unnamed module of loader 'app')
    at zio.actors.ActorSystem$.$anonfun$apply$1$adapted(ActorSystem.scala:34)
    at zio.internal.FiberContext.evaluateNow(FiberContext.scala:350)
    at zio.internal.FiberContext.$anonfun$fork$15(FiberContext.scala:767)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

Fiber:Id(1595333184488,1) was supposed to continue to:
  a future continuation at MyApp$.program(MyApp.scala:41)
  a future continuation at zio.ZIO.exitCode(ZIO.scala:578)

Fiber:Id(1595333184488,1) execution trace:
  at zio.actors.ActorSystem$.apply(ActorSystem.scala:34)
  at zio.ZRef$.make(ZRef.scala:609)

Fiber:Id(1595333184488,1) was spawned by:

Fiber:Id(1595333184392,0) was supposed to continue to:
  a future continuation at zio.App.main(App.scala:57)
  a future continuation at zio.App.main(App.scala:56)

Fiber:Id(1595333184392,0) ZIO Execution trace: <empty trace>

Fiber:Id(1595333184392,0) was spawned by: <empty trace>

Process finished with exit code 1

Any help !! [1]: https://zio.github.io/zio-actors/docs/usecases/usecases_pingpong


Solution

  • Checked it and I recalled that this doc site wasn't updated after API changes - you need to provide configFile pointing to application.conf enabling remote configuration. Sorry for that, will update it in the next release and I hope to make it more ergonomic in the future (as it's still prototype).

    Please refer to https://github.com/zio/zio-actors/blob/master/actors/src/test/scala/zio/actors/RemoteSpec.scala#L100 test case:

    val configFile = Some(new File("./src/test/resources/application.conf"))
    ... <- ActorSystem("...", configFile)
    

    Here's scaladoc with details: https://github.com/zio/zio-actors/blob/master/actors/src/main/scala/zio/actors/ActorSystem.scala#L24