我希望能够订阅“Exchange”(类似于在熟悉的情况下在主题交换中通过RabbitMQ中的哈希订阅),之后,发布到给定类型的交换的所有消息都被转发给订户。所以基本上每种类型代表一个渠道。
我已经能够使用案例对象进行测试(只是让它先工作然后重构为正确的设计)。但是使用案例类,我不知道该怎么做。我可以创建一个类的新实例化并将其传入。但是,我想传入类型,而不是它的对象。然后根据类型进行匹配。
我正在考虑传递一个类的对象,并保持它匹配,如果它是相同的类型,但这似乎我只是管道绑在一起,因为我不知道我在做什么。有人有什么建议吗?
describe("Subscribe") {
it("should add the subscriber to the list of subscribers for the given channel (message type)", LibraryTest) {
import lib.exchange.ExchangeInterface.{ TestCommand, Subscribe }
val exchange = TestActorRef(new Exchange)
val probe = TestProbe()
exchange ! Subscribe(probe.ref, /*Insert Type Here*/)
awaitCond(exchange.underlyingActor.subscribers.get(/* Channel/Type */).get.contains(probe.ref))
}
}
object ExchangeInterface {
case class Subscribe(subscriber: ActorRef, channel: Command)
trait Command
case class TestCommand(message: Any) extends Command
}
class Exchange extends Actor with ActorLogging {
import ExchangeInterface.{ Command, Subscribe }
val name = self.path.name
var subscribers = HashMap[Any, Set[ActorRef]]()
def receive = {
case Subscribe(subscriber: ActorRef, channel: Command) => subscribers(channel) += subscriber
}
}
答案 0 :(得分:1)
您可以简单地传入类的完全限定名称,而不是传入类型,对象。它应该工作[*],并会简化一些事情:
exchange ! Subscribe(probe.ref, classOf[TestCommand].getName)
[...]
var subscribers = mutable.HashMap[String, Set[ActorRef]]()
def receive = {
case Subscribe(subscriber: ActorRef, channel: String) => subscribers(channel) += subscriber
}
如果你想要一点类型的安全性,而不是只有弦乐飞来飞去:
case class Channel(name: String)
object Channel{
def from(clazz: Class[_]) = Channel(clazz.getName)
}
object ExchangeInterface {
case class Subscribe(subscriber: ActorRef, channel: String)
trait Command {
def channel = Channel.from(this.getClass)
}
case class TestCommand(message: Any) extends Command
}
class Exchange extends Actor with ActorLogging {
import ExchangeInterface.Subscribe
val name = self.path.name
var subscribers = mutable.HashMap[Channel, Set[ActorRef]]()
def receive = {
case Subscribe(subscriber: ActorRef, channel: Channel) => subscribers(channel) += subscriber
}
}
这为您提供了两种订阅频道的方式:
exchange ! Subscribe(probe.ref, Channel.from(classOf[TestCommand]))
val command = TestCommand("Message")
exchange ! Subscribe(probe.ref, command.channel)
[*]它不适用于在编译时删除其类型的泛型。所以java.util.ArrayList [Int]将与java.util.ArrayList [String]相同。