代码之家  ›  专栏  ›  技术社区  ›  davidrpugh

在mixin中访问Akka Actor上下文

  •  0
  • davidrpugh  · 技术社区  · 7 年前

    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 回复  |  直到 7 年前
        1
  •  0
  •   shayan    7 年前

    我建议使用actor的生命周期事件挂钩来控制时间表的触发器。如果你有这样一个演员:

    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?
      }    
    }
    

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

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

        2
  •  0
  •   Ryan    7 年前

    你可以使用“自我类型”来要求演员只混合一种特质。

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

    MyMixin 不是吗 一个actor,但它只能由作为actor的类扩展。