我试图为Play 2.5中的演员定义一个自定义邮箱,保证邮件的唯一性和优先级。
我得到了这个例外:
CreationException: Unable to create injector, see the following errors:
1) Error in custom provider, akka.ConfigurationException: Type [jobs.SteamInfoUpdater.MyPrioQueueSematics] specified as akka.actor.mailbox.requirement [unique-prio-mailbox] in config can't be loaded due to [jobs.SteamInfoUpdater.MyPrioQueueSematics]
while locating play.api.libs.concurrent.ActorSystemProvider
while locating akka.actor.ActorSystem
for field at play.api.libs.concurrent.ActorRefProvider.actorSystem(Akka.scala:205)
while locating play.api.libs.concurrent.ActorRefProvider
at com.google.inject.util.Providers$GuicifiedProviderWithDependencies.initialize(Providers.java:149)
at play.api.libs.concurrent.AkkaGuiceSupport$class.bindActor(Akka.scala:139) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.ServiceModule)
我的配置中有以下内容:
unique-prio-mailbox{
mailbox-type = "jobs.SteamInfoUpdater.UniquePriorityMailbox"
}
akka.actor.mailbox.requirements {
"jobs.SteamInfoUpdater.MyPrioQueueSematics" = unique-prio-mailbox
}
我认为问题与配置无法加载MyPriorityQueueSemantics
有关,因为如果我将配置更改为:
akka.actor.mailbox.requirements {
"test" = unique-prio-mailbox
}
我明白了:
Error in custom provider, akka.ConfigurationException: Type [test] specified as akka.actor.mailbox.requirement [unique-prio-mailbox] in config can't be loaded due to [test]
这是我的邮箱实现:
trait MyPrioQueueSematics
class UniquePriorityMessageQueue extends MessageQueue
with MyPrioQueueSematics {
private final val queue = new UniquePriorityBlockingQueue[Envelope](500, Ordering.by(e => e.message match {
case m: InfoUpdaterMessage => m.priority
case _ => Int.MaxValue
}))
def enqueue(receiver: ActorRef, handle: Envelope): Unit =
queue.offer(handle)
def dequeue(): Envelope = queue.poll()
def numberOfMessages: Int = queue.size
def hasMessages: Boolean = !queue.isEmpty
def cleanUp(owner: ActorRef, deadLetters: MessageQueue) {
while (hasMessages) {
deadLetters.enqueue(owner, dequeue())
}
}
}
class UniquePriorityBlockingQueue[T](initialCapacity: Int, ordering: Ordering[T]) extends ForwardingQueue[T] {
override def delegate(): util.Queue[T] = new PriorityBlockingQueue[T](initialCapacity, ordering)
override def add(element: T): Boolean = if (super.contains(element)) {
false
} else {
super.add(element)
}
override def offer(o: T): Boolean = standardOffer(o)
}
class UniquePriorityMailbox extends MailboxType with ProducesMessageQueue[UniquePriorityMessageQueue] {
def this(settings: ActorSystem.Settings, config: Config) = {
this()
}
final override def create(
owner: Option[ActorRef],
system: Option[ActorSystem]): MessageQueue =
new UniquePriorityMessageQueue()
}
我已遵循本指南:http://doc.akka.io/docs/akka/snapshot/scala/mailboxes.html