在mixin

时间:2017-07-18 12:38:25

标签: scala akka mixins akka-actor

我想定义一个可以与Akka actor混合的特性,该演员在一段有限的持续时间后调度接收超时。这是我想要做的草图......

trait BidderInActivityClearingSchedule[T <: Tradable, A <: Auction[T, A]]
    extends ClearingSchedule[T, A] {
  this: AuctionActor[T, A] =>

  context.setReceiveTimeout(timeout)  // can I call this here?

  def timeout: FiniteDuration

  override def receive: Receive = {
    case ReceiveTimeout =>
      val (clearedAuction, contracts) = auction.clear
      contracts.foreach(contract => settlementService ! contract)
      auction = clearedAuction
    case message => this.receive(message)
  }

}


class FancyAuctionActor[T <: Tradable](val timeout: FiniteDuration, ...)
    extends AuctionActor[T, FancyAuctionActor[T]]
    with BidderInActivityClearingSchedule[T, FancyAuctionActor[T]]

...但我不明白何时会调用context.setReceiveTimeout。调用MyFancyAuctionActor时,它是否会被调用为构造函数的一部分?或者它会被提前调用,从而因为timeout尚未定义而引发某种错误。

2 个答案:

答案 0 :(得分:0)

我建议使用actor的生命周期事件hook来控制你的日程表的触发器。如果你的特性扩展了这样的演员:

trait AuctionActor[T, A] extends Actor
trait BidderInActivityClearingSchedule[T, A] extends AuctionActor[T,A] 

您可以访问演员的许多生命周期事件挂钩,例如preStart()postStop()等等。

所以你可以很容易地做到:

trait BidderInActivityClearingSchedule[T, A] extends AuctionActor[T,A] {
  override def preStart() = {
    supre.preStart() // or call this after the below line if must.
    context.setReceiveTimeout(timeout)  // can I call this here?
  }    
}

更新

如果要实现可堆叠的mixins结构。你会做类似上面的事情。

//your AuctionActor is now a class as you wanted it
class AuctionActor[T, A] extends Actor

//Look below; the trait is extending a class! it's ok! this means you can 
//only use this trait to extend an instance of AuctionActor class 
trait BidderInActivityClearingSchedule[T, A] extends AuctionActor[T,A]{
  def timeout: FiniteDuration

  //take note of the weird "abstract override keyword! it's a thing!"
  abstract override def preStart() = {
    super.preStart()
    context.setReceiveTimeout(timeout)
  }
}

您可以拥有尽可能多的特征,将您的类AuctionActor扩展到一起。

答案 1 :(得分:0)

您可以使用自我类型来要求将特征仅混合到Actors中。

trait MyMixin { self: Actor =>
  println(self.path)
}

trait MyActor extends Actor with MyMixin

MyMixin不是相当一个演员,但它只能由演员的类扩展。