在 mixin 中访问 Akka Actor 上下文

Accessing Akka Actor context inside a mixin

我想定义一个可以与 Akka actor 混合使用的特征,该 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 尚未定义。

我建议使用 actor 的生命周期事件来控制你的日程表的触发器 hooks.if 你有你的特征扩展这样的 actor:

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

您将可以访问 actor 的许多生命周期事件挂钩,例如 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?
  }    
}

更新

如果你想实现一个可堆叠的混合结构。你会做类似于上面的事情。

//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)
  }
}

您可以拥有尽可能多的扩展 class AuctionActor 堆叠在一起的特征。

您可以使用自我类型来要求特征只能混入到 Actors 中。

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

trait MyActor extends Actor with MyMixin

MyMixin完全演员,但它只能由类作为演员来扩展。