Scala 无法在Akka流中使用GraphStage类运行SourceShape

Scala 无法在Akka流中使用GraphStage类运行SourceShape,scala,akka,akka-stream,Scala,Akka,Akka Stream,我正在尝试使用GraphStage构造创建一个Redis Akka流源。其思想是,每当我从subscribe方法获得更新时,我都会将其推送到下一个组件。此外,如果没有拉力信号,部件应承受背压。代码如下: class SubscriberSourceShape(channel: String, subscriber: Subscriber) extends GraphStage[SourceShape[String]] { private val outlet: Outlet[St

我正在尝试使用GraphStage构造创建一个Redis Akka流源。其思想是,每当我从subscribe方法获得更新时,我都会将其推送到下一个组件。此外,如果没有拉力信号,部件应承受背压。代码如下:

class SubscriberSourceShape(channel: String, subscriber: Subscriber) 
    extends GraphStage[SourceShape[String]] {

  private val outlet: Outlet[String] = Outlet("SubscriberSource.Out")

  override def shape: SourceShape[String] = SourceShape(outlet)

  override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = {
    new GraphStageLogic(shape) {
      val callback = getAsyncCallback((msg: String) => push(outlet, msg)
      val handler = (msg: String) => callback.invoke(msg)

      override def preStart(): Unit = subscriber.subscribe(channel)(handler)
    }
  }
}
但是,当我使用一个简单的接收器运行此命令时,会出现以下错误:

[akka.http.impl.engine.server.HttpServerBluePrint]阶段中出现错误$ProtocolSwitchStage@58344854]:在阶段[…]中未定义处理程序。。。SubscriberSourceShape@6a9193dd]对于out端口[RedisSubscriberSource.out(1414886352)]。必须在图形阶段逻辑的构造函数中为所有入口和出口分配一个带有setHandler的处理程序。


有什么问题吗?

您之所以会出现此错误,是因为您没有为源设置任何输出处理程序,因此当下游组件(流或汇)向该源发送拉信号时,没有处理程序来处理拉信号

您可以添加OutputHandler以消除错误。由于您在asyncCallback上生成元素,因此请将onPull方法保留为空。只需在GraphStageLogic正文中添加以下内容:

      setHandler(outlet, new OutHandler {
        override def onPull(): Unit = {}
      })

Subscriber
来自哪里?另外,您是否需要创建一个自定义的graph stage,或者您是否愿意使用任何产生
源[String,\uu]的解决方案
?订阅者是redisClient.subscribe调用的包装器。它使用频道名称和回调函数来处理PubSub频道的即将到来的消息。任何产生源[字符串,\ux]的解决方案不过,这也没关系,因为我无法控制元素的生成时间,所以定制图形阶段是一种选择。我还使用Source.queue和Source.actorRef实现了解决方案。但它们都有各自的缺点。