我有一个演员,在后台每小时下载一个大约100万行的CSV产品文件,然后它会遍历CSV并改变一个集合。
现在在我的游戏控制器中,我将向网站访问者显示这100万行的子集。
我将向演员发出请求,要求我提供该集合的副本。 如果我是按页面请求执行此操作,这是性能问题吗?或者拨打下面的电话非常接近作业?
val futProducts = myActor ? GetProducts
我的演员将有一系列产品每隔一小时就会升级。
var products: List[Product] = ...
更新
我怎么能创建一个对这个products
变量的全局引用,我可以在我的播放控制器中引用它,然后也可以在我的actor中变异。我认为这是最好的方法,但不知道该怎么做。
答案 0 :(得分:1)
我不会通过对products
变量的全局引用来解决这个问题,因为这意味着你有一个共享的可变状态。我会采用你的第一种方法将这些产品列表封装在你的演员中:
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更新其数据时,缓存会失效,这样当您请求新的/未知页面时,您只能访问实际的数据actor。