Scala 如何使用akka流中的mapAsync使用分组子流

Scala 如何使用akka流中的mapAsync使用分组子流,scala,stream,akka-stream,Scala,Stream,Akka Stream,我需要做一些真正类似的事情 我的问题是,我有一个未知数量的组,如果mapAsync的并行数小于我得到的组数,那么在最后一个接收器中会出错 拆毁 SynchronousFileLink(/Users/sam/dev/projects/akka streams/target/log ERROR.txt) 由于上游错误 (akka.stream.impl.StreamSubscriptionTimeoutSupport$$anon$2) 我试图在AkkAsvs模式指南中提出一个中间缓冲区。 但同样的结

我需要做一些真正类似的事情

我的问题是,我有一个未知数量的组,如果mapAsync的并行数小于我得到的组数,那么在最后一个接收器中会出错

拆毁 SynchronousFileLink(/Users/sam/dev/projects/akka streams/target/log ERROR.txt) 由于上游错误 (akka.stream.impl.StreamSubscriptionTimeoutSupport$$anon$2)

我试图在AkkAsvs

模式指南中提出一个中间缓冲区。
但同样的结果

扩展了jrudolph的评论,这是完全正确的

在此实例中,不需要
mapsync
。作为一个基本示例,假设您有一个元组源

import akka.stream.scaladsl.{Source, Sink}

def data() = List(("foo", 1),
                  ("foo", 2),
                  ("bar", 1),
                  ("foo", 3),
                  ("bar", 2))

val originalSource = Source(data)
然后,您可以执行groupBy来创建

每一个分组的源都可以通过一个
映射来并行处理,无需任何花哨的东西。以下是在独立流中汇总每个分组的示例:

import akka.actor.ActorSystem
import akka.stream.ACtorMaterializer

implicit val actorSystem = ActorSystem()
implicit val mat = ActorMaterializer()
import actorSystem.dispatcher

def getValues(tuple : (String, Int)) = tuple._2

//does not have to be a def, we can re-use the same sink over-and-over
val sumSink = Sink.fold[Int,Int](0)(_ + _)

//a Source of (String, Future[Int])
val sumSource  = 
  groupedSource map { case (id, src) => 
    id -> {src map getValues runWith sumSink} //calculate sum in independent stream
  }
现在所有的
“foo”
数字与所有的
“bar”
数字并行相加


mapsync
用于当您有一个返回
Future[T]
的封装函数,并且您试图发出
T
时;你的问题不是这样的。此外,mapAsync涉及的不是…

我想知道使用
mapAsync
是否有任何用途?如果只使用
map
会发生什么?使用map时,组不会以并行/异步方式使用,这是我想要的行为。我认为这是一个误解。所有的组都由一个
Source[Something]
表示(在
groupBy
之后,您有一个
Source[Source[Something]
,对吗?)。因此,在
映射
(foreach
也应该工作)中,您需要做的唯一一件事就是运行子流,这是一个异步操作。然后子流将自行运行,并且您的
映射
元素将可以自由地接受下一个
源[Something]
。现在akka流已与akka流合并,并且源语义的源已替换为子流,一个人怎样才能完成类似的行为?@AlphaGeek我注意到groupBy功能几个月前发生了变化。cookbook有一个基于新的子流方法的更新示例:@RamonJRomeroyVigil cookbook没有解释它。他们使用reduce,如果我们在每个子流中都有项目的竖梃,这是不可行的。我(也是作者)想要的是每组获得
Source
。我们将如何做到这一点?是否对此有过解决方案?@Zee不幸的是,子流的新实现没有传递与子流相关的密钥。因此,我不知道如何生成问题中要求的输出。。。
def getID(tuple : (String, Int)) = tuple._1

//a Source of (String, Source[(String, Int),_])
val groupedSource = originalSource groupBy getID
import akka.actor.ActorSystem
import akka.stream.ACtorMaterializer

implicit val actorSystem = ActorSystem()
implicit val mat = ActorMaterializer()
import actorSystem.dispatcher

def getValues(tuple : (String, Int)) = tuple._2

//does not have to be a def, we can re-use the same sink over-and-over
val sumSink = Sink.fold[Int,Int](0)(_ + _)

//a Source of (String, Future[Int])
val sumSource  = 
  groupedSource map { case (id, src) => 
    id -> {src map getValues runWith sumSink} //calculate sum in independent stream
  }