【问题标题】:Creating an in-memory storage using Akka actors使用 Akka Actor 创建内存存储
【发布时间】:2014-03-17 08:01:36
【问题描述】:

我正在尝试使用一个宠物项目来熟悉 Akka。这基本上是一个锦标赛式的服务器,拥有一群玩家。在每一轮中,它应该从池中随机抽取两名玩家,让他们互相对战,然后更新记分牌。整个事情都位于 HTTP 服务器后面。玩家通过 HTTP Post 消息添加,游戏通过从 JS 客户端发送的“Play”消息触发。

我想到的实现方式如下:

  • 一个 PlayerPool Actor 处理两条消息,“AddPlayer”和“Play”
  • Round Actor 接收两个玩家的消息,玩一轮,然后更新
  • GameResults 演员,包含已玩回合的列表和每回合的获胜者。它还显示返回记分牌的“GetScore”消息。
  • HTTP 层是一个喷雾路由参与者,公开对“GetScore”、“AddPlayer”和“Play”的调用,与 PlayerPool 和 GameResults 参与者对话。

我的问题是两个独立的actor正在与 GameResults 对话——直接与 Spray 和 Round actor 对话,显然正在创建 GameResults 的两个独立实例,因此当 Round 将结果添加到一个实例时,Spray 正在读取另一个实例的记分牌。显然我错过了一些非常基本的东西,在尝试解决问题之前,我想了解在 Akka 中这样做的规范方式是什么?基本上这个问题可以简化为一个actor,它在不同的调用中保持一个状态。

很高兴有人指出我正确的方向。

【问题讨论】:

  • 显示一些代码,不需要初始化GameResults 2次,可以是单个actor持有结果。
  • 两个actor中的同一行代码:val gameResults: ActorRef = context.actorOf(Props[GameResults], "results")
  • 这在代码中是否只调用过一次?
  • 两次。来自两个不同的演员。
  • 所以你要创建 2 个不同的 Actor,你应该只初始化一次 Actor,如果你需要从另一个 Actor 向特定 Actor 发送消息,请使用 Actor ref

标签: scala akka


【解决方案1】:

代码 sn-p 示例如何将消息从 Spray 传递到您的游戏结果 Actor:

希望对你有帮助

        object SomeApp extends App{

        //create a actor system
          val yourSystem = ActorSystem("Your-System")

          //init spray actor
          val restHandler = yourSystem.actorOf(Props[RestHandler], name = "Rest-spray")

          //init play pool actor
          val playerPoolActor = yourSystem.actorOf(Props[PlayerPool], name = "playerPool")

          //INIT ONLY 1 game result actor
          val gameResultsActor  = yourSystem.actorOf(Props[GameResults], name = "gameResults")

          //spray listen to all IP on port 90210
          IO(Http)(yourSystem) ! Http.Bind(restHandler, interface = "0.0.0.0" , port = 90210)

          class RestHandler extends Actor with RestHandlerRoute  {
            def actorRefFactory = context
            //nice to hold the route in a diffrent trait
            def receive = runRoute(someRoute)
          }
        }

        //only thing the trait is doing is configuring the routing and send message to relavant actor
        trait RestHandlerRoute extends HttpService{me: Actor =>
          import SomeApp._

          val someRoute =
            path("getGameResults")  { get { respondWithMediaType(`text/html`) { complete {
                //case the user requested http://someIP:90210/getGameResults spray will send a message to the game result actor
                gameResultsActor ! getResult
            } ~
        }

【讨论】:

  • 我真的不明白你如何将 GameResults 演员引用从 SomeApp 传递给 RestHandlerRoute(你这样做吗?)。另外,我将如何将引用传递给 Round Actor(然后需要将结果发送到 GameResults)?
  • import SomeApp._ 让我可以访问对象成员。其中 1 个是名为 gameResultActor 的演员 ref
  • 在我看来,这并不是在 Akka 中做这类事情的规范方式。但我可能错了……
  • 这只是一个如何使用 Spray 向 Actor 发送消息的示例。如果您找到适合您的规范方式。请分享。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-17
  • 1970-01-01
  • 2019-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-09
  • 2016-10-09
相关资源
最近更新 更多