【发布时间】:2020-10-24 23:38:45
【问题描述】:
我必须填写模板才能在购物车上实现超时。到目前为止,我有:
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) 时,计时器是在任何地方隐式调用,还是刚刚通过?
【问题讨论】:
标签: scala timer akka scheduler