我必须填写模板来实现购物车超时。到目前为止我有:
import akka.actor.{Actor, ActorRef, Cancellable, Props, Timers}
import akka.event.{Logging, LoggingReceive}
import scala.concurrent.duration._
import scala.language.postfixOps
object CartActor {
sealed trait Command
case class AddItem(item: Any) extends Command
case class RemoveItem(item: Any) extends Command
case object ExpireCart extends Command
case object StartCheckout extends Command
case object ConfirmCheckoutCancelled extends Command
case object ConfirmCheckoutClosed extends Command
sealed trait Event
case class CheckoutStarted(checkoutRef: ActorRef) extends Event
def props = Props(new CartActor())
}
class CartActor extends Actor with Timers {
import context._
import CartActor._
private val log = Logging(context.system, this)
val cartTimerDuration: FiniteDuration = 5 seconds
var cart: Cart = Cart.empty
private def scheduleTimer: Cancellable =
system.scheduler.scheduleOnce(cartTimerDuration, self, ExpireCart)
def receive: Receive = empty
def empty: Receive = {
case AddItem(item) =>
this.cart = cart.addItem(item)
scheduleTimer
context become nonEmpty(cart, scheduleTimer)
case _ =>
}
def nonEmpty(cart: Cart, timer: Cancellable): Receive = {
case AddItem(item) =>
this.cart = cart.addItem(item)
timer.cancel()
scheduleTimer
case RemoveItem(item) =>
this.cart = this.cart.removeItem(item)
if (this.cart.size != 0) {
timer.cancel()
scheduleTimer
}
else
context become empty
case StartCheckout =>
context become inCheckout(this.cart)
case ExpireCart =>
this.cart = Cart.empty
println("Cart expired")
context become empty
}
def inCheckout(cart: Cart): Receive = {
case ConfirmCheckoutCancelled =>
context become nonEmpty(cart, scheduleTimer)
case ConfirmCheckoutClosed =>
println("Cart closed after checkout")
context become empty
case _ =>
}
}
提供了方法签名,因此,例如,我无法更改def nonEmpty(cart: Cart, timer: Cancellable)
。在添加或删除项目时,计时器应该重置,因此用户有5秒时间来做一些事情。问题是,我不知道如何正确地做到这一点-上面的方法显然没有重置计时器,因为它总是在5秒后超时。我如何才能做到这一点?我应该使用计时器而不是调度程序吗?例如timers.startSingleTimer("ExpireCart", ExpireCart, cartTimerDuration)
?我应该如何在方法之间传递它?计时器应该是CartActor的属性,而我应该忽略调度程序吗?顺便说一句,当我有def nonEmpty(cart: Cart, timer: Cancellable)
时,计时器是在任何地方隐式调用,还是直接传递?
1条答案
按热度按时间lg40wkob1#
有两个问题。
首先,在
empty
中启动两个计时器:更一般地说,您在receive方法中同时使用了mutable state * 和 * 参数。mutable state不是必需的,因此请删除以下行:
现在修复
nonEmpty
,将更新后的状态传递给新的receive
方法,而不是使用this
: