在 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
不完全演员,但它只能由类作为演员来扩展。
我想定义一个可以与 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
不完全演员,但它只能由类作为演员来扩展。