Scala 在集合中存储100万行,在参与者中更新

Scala 在集合中存储100万行,在参与者中更新,scala,playframework,akka,Scala,Playframework,Akka,我有一个演员,在后台每小时下载一个大约100万行的CSV产品文件,然后它会在CSV中循环并改变一个集合 现在,在我的播放控制器中,我将向网站访问者显示这100万行中的一个子集 我将要求演员给我一份收藏的副本如果我按每页请求执行此操作,这是否会导致性能问题?还是说打下面这样的电话很接近任务? val futProducts = myActor ? GetProducts 我的演员会有一系列的产品,每小时都会更新一次 var products: List[Product] = ... 更新 我如

我有一个演员,在后台每小时下载一个大约100万行的CSV产品文件,然后它会在CSV中循环并改变一个集合

现在,在我的播放控制器中,我将向网站访问者显示这100万行中的一个子集

我将要求演员给我一份收藏的副本如果我按每页请求执行此操作,这是否会导致性能问题?还是说打下面这样的电话很接近任务?

val futProducts = myActor ? GetProducts
我的演员会有一系列的产品,每小时都会更新一次

var products: List[Product] = ...
更新


我如何创建对这个
产品
变量的全局引用,我可以在我的游戏控制器中引用,然后也可以在我的演员中变异。我认为这是最好的方法,但不确定如何做到这一点。

我不会通过全局引用您的
产品
变量来解决这个问题,因为这意味着您拥有一个共享的可变状态。我将采用您的第一种方法,将产品列表封装到您的actor中,如下所示:

import DataActor.{Page, Update}
import akka.actor.Actor

/**
  * Created by d058837 on 19.06.17.
  */
class DataActor extends Actor {

  var data: Seq[Int] = 1 to 100000
  val pageSize = 100

  override def receive: Receive = {
    case Update =>
      updateData()
    case Page(page) =>
      sender() ! data.slice(pageSize * page, pageSize * page + pageSize)
  }

  def updateData() = {
    data = data.map(_ + 100)
  }

}

object DataActor {

  case object Update
  case class Page(page: Int = 0)
}
如本测试所示,您可以使用:

import akka.actor.{ActorSystem, Props}
import akka.pattern.ask
import akka.testkit.{ImplicitSender, TestKit}
import akka.util.Timeout
import org.scalatest.{Matchers, WordSpecLike}

import scala.concurrent.Await
import scala.concurrent.duration.DurationInt

class DataActorTest extends TestKit(ActorSystem("testSystem")) with WordSpecLike with Matchers with ImplicitSender {

  "actor with data should" should {
    "update data and return pages" in {
      implicit val timeout: Timeout = 3 seconds

      val dataActor = system.actorOf(Props[DataActor])

      val initialStateFuture = dataActor ? DataActor.Page(0)
      val initialState = Await.result(initialStateFuture, timeout.duration)
      initialState shouldBe (1 to 100)

      dataActor ! DataActor.Update

      val currentStateFuture = dataActor ? DataActor.Page(0)
      val currentState = Await.result(currentStateFuture, timeout.duration)
      currentState shouldBe (101 to 200)
    }
  }
}
我肯定会在这里使用分页的方法,这样您就不会一直在大量的产品列表中移动


为了获得更高的性能,您可以在控制器中使用缓存,当DataActor更新其数据时,缓存将失效,因此,只有在请求新的/未知的页面时,您才能访问实际的data actor。

许多因素会影响性能。如果您正在执行多页请求,则可能需要为每个页面创建
n
参与者。