2017-07-18 100 views
0

我想定义一个可以与Akka actor混合的特性,该特性可以在一定的持续时间之后调度接收超时。这里是什么,我想要做一个素描......访问mixin中的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尚未定义。

回答

0

我建议你的日程安排的控制触发使用演员的生命周期事件hooks.if你有你的特质延长像这样的演员:

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

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

+0

使用actor生命周期钩子并不是一个坏主意,但我不想扩展Actor我想保持特性为混合。 – davidrpugh

+0

据我所知,可堆叠mixin的最佳实践方法是让所有mixin扩展基本特征。你实际上只是在你的情况下使用自我类型注释来做同样的事情,而你却剥夺了重载方法的优势。还有另一个技巧来实现可堆叠的mixin,我将其描述为更新回答 – shayan

+0

我熟悉可堆叠的actor模式,并在库中使用它。也许我很迂腐,但我不喜欢有明显的mixin从Actor延伸出来的特质。 – davidrpugh

0

你可以使用自我类型来要求一个特质只能混入到Actors中。

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

trait MyActor extends Actor with MyMixin 

MyMixin相当演员,但它只能通过是演员的类进行扩展。

+0

我向mixin提供了一个自我类型注释,以强制它必须与AuctionActor(它扩展了Actor)混合的约束。任何使用“自我”而不是“本”的理由? – davidrpugh

+0

你可以任意调用它。 – Ryan