【问题标题】:Akka Pattern Match on Generic Type泛型类型上的 Akka 模式匹配
【发布时间】:2018-06-20 00:33:22
【问题描述】:

我有一个 Actor 实例,定义如下:

class KafkaPublisher[T <: KafkaMessage] extends Actor {

  override final def receive = {
    case ProducerStreamActivated(_, stream: SourceQueueWithComplete[T]) =>
      context.become(active(stream))

    case other => println("KafkaPublisher got some unknown message while producing: " + other)
  }

  def active(stream: SourceQueueWithComplete[T]): Receive = super.receive orElse {
    case msg: T =>
      stream.offer(msg)

    case other => println("KafkaPublisher got the unknown message while producing: " + other)
  }
}
object KafkaPublisher {

  def props[T <: KafkaMessage](implicit tag: ClassTag[T]) = Props(new KafkaPublisher[T])
}

KafkaMessage 是一个标记特征,我想发布到 Kafka 的每条消息都将扩展这个标记特征。我有一个主管 Actor,它实际上将根据 Kafka 消息的类型创建此 KafkaPublisher Actor 的实例。例如,

case class MeterData(id: String, meterReadings: Map[DateTime, String]) extends KafkaMessage

所以在我的 SupervisorActor 中,我创建了一个 PublisherActor 的实例,如下所示:

def actorFor(props: Props, actorName: String) = context.actorOf(props, actorName)
val actorRef = actorFor(KafkaPublisher.props[MeterData], "meter-data-actor")

同样,我为给定的 KafkaMessage 类型创建了相应的 Akka 流。

所以我的问题是,考虑到我定义了通用模式匹配,这个 KafkaPublisher 演员模式是否会匹配 MeterData。我的 props 方法中的 ClassTag 是否足以让我通过类型擦除?有什么建议吗?

【问题讨论】:

    标签: scala generics apache-kafka akka akka-stream


    【解决方案1】:

    泛型类型T 上的模式匹配应该可以工作,当范围内有隐式ClassTag[T] 时。因此,在您的KafkaPublisher 中提供和存储ClassTag 就足够了:

    import scala.reflect.ClassTag
    
    class KafkaPublisher[T <: KafkaMessage : ClassTag] {
      /* ... */
    }
    
    object KafkaPublisher {
      def props[T <: KafkaMessage : ClassTag] = Props(new KafkaPublisher[T])
    }
    

    如果T 类型在props 调用站点上是具体的,或者它是通用的但那里有一个隐含的ClassTag[T],那么您可以像往常一样调用propsactorFor(KafkaPublisher.props[MeterData], "meter-data-actor")

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 2020-09-02
    • 2016-10-29
    • 2016-09-04
    相关资源
    最近更新 更多