Scala 在Akka流中确认SQS消息的正确方式是什么

Scala 在Akka流中确认SQS消息的正确方式是什么,scala,akka,akka-stream,Scala,Akka,Akka Stream,假设我有一个来自AWS的SQS消息流。我有一个流,它接收消息并执行一些可能不安全的副作用 我想确认所有消息,如果进程因任何原因失败,我想将消息推送到另一个队列。如果进程成功,我想删除它。我不想没有确认信息 我还希望能够将传入的消息分派到并行化的工作进程中 做这种事的正确方法是什么 我认为这是可行的,但我想知道这是否是一个“好”的解决方案: val flow=flow[String] .map{value=> 如果(值=“全局”) 抛出新异常(“意外故障解析全局”) println(值) } va

假设我有一个来自AWS的SQS消息流。我有一个流,它接收消息并执行一些可能不安全的副作用

我想确认所有消息,如果进程因任何原因失败,我想将消息推送到另一个队列。如果进程成功,我想删除它。我不想没有确认信息

我还希望能够将传入的消息分派到并行化的工作进程中

做这种事的正确方法是什么

我认为这是可行的,但我想知道这是否是一个“好”的解决方案:

val flow=flow[String]
.map{value=>
如果(值=“全局”)
抛出新异常(“意外故障解析全局”)
println(值)
}
val结果=源(
Seq(“coucou”、“baba”、“global”、“besible”、“test”、“lol”、“supercool”)
)
.mapsync(2){el=>
来源
.单人(el)
.通过(流量)
.恢复{
案例示例:可丢弃=>
println(s“将消息${el}发送到另一个队列”)
}
.runWith(Sink.foreach{{\u=>
println(s“删除邮件${el}”)
})
}
.runWith(Sink.ignore)

你觉得怎么样?

流程中,你可以简单地将其包装在
中,而不是执行副作用,这样你就可以用
nok
ok
分别处理左右

导入akka.actor.ActorSystem
导入akka.stream.SinkShape
导入akka.stream.scaladsl.{Flow,GraphDSL,Partition,Sink,Source}
导入scala.concurrent.ExecutionContext
对象分区流{
def main(参数:数组[字符串]):单位={
隐式val系统:ActorSystem=ActorSystem(“PartitionStream”)
隐式val ec:ExecutionContext=system.dispatcher
val flow=flow[String]。映射{value=>
如果(值=“全局”)
左(MyException(“意外故障解析全局”))
其他权利(价值)
}
val sink=sink.fromGraph(GraphDSL.create(){implicit b=>
导入GraphDSL.Implicits_
val partition=b.add(
分区[MyException,String]](2,el=>if(el.isLeft)0或1)
)
val collectNok=Flow[MyException,String]]中的任意一个。collect{
案例左侧(ex)=>ex
}
val collectOk=Flow[MyException,String]]中的任意一个。collect{
案例右侧(值)=>值
}
val nok=b.add(Sink.foreach[MyException](x=>println(x.msg)))
val ok=b.add(Sink.foreach[String](println))
partition.out(0)~>collectNok~>nok
partition.out(1)~>collectOk~>ok
SinkShape(分区.in)
})
来源(
列表(“coucou”、“baba”、“全局”、“明显”、“测试”、“lol”、“超级冷”)
).通孔(流量).运行(水槽)
}
案例类MyException(消息:字符串)
}

流程中
不执行副作用,也许您可以简单地将其包装在
中,以便使用
nok
ok
以不同的方式处理左右

导入akka.actor.ActorSystem
导入akka.stream.SinkShape
导入akka.stream.scaladsl.{Flow,GraphDSL,Partition,Sink,Source}
导入scala.concurrent.ExecutionContext
对象分区流{
def main(参数:数组[字符串]):单位={
隐式val系统:ActorSystem=ActorSystem(“PartitionStream”)
隐式val ec:ExecutionContext=system.dispatcher
val flow=flow[String]。映射{value=>
如果(值=“全局”)
左(MyException(“意外故障解析全局”))
其他权利(价值)
}
val sink=sink.fromGraph(GraphDSL.create(){implicit b=>
导入GraphDSL.Implicits_
val partition=b.add(
分区[MyException,String]](2,el=>if(el.isLeft)0或1)
)
val collectNok=Flow[MyException,String]]中的任意一个。collect{
案例左侧(ex)=>ex
}
val collectOk=Flow[MyException,String]]中的任意一个。collect{
案例右侧(值)=>值
}
val nok=b.add(Sink.foreach[MyException](x=>println(x.msg)))
val ok=b.add(Sink.foreach[String](println))
partition.out(0)~>collectNok~>nok
partition.out(1)~>collectOk~>ok
SinkShape(分区.in)
})
来源(
列表(“coucou”、“baba”、“全局”、“明显”、“测试”、“lol”、“超级冷”)
).通孔(流量).运行(水槽)
}
案例类MyException(消息:字符串)
}

为什么要从单个elment创建源?。您可以使用Graph DSL创建另一个流,并使用分区将错误重定向到另一个队列,因为我希望ACK严格发生在内部流结束之后。但也许它会发生在使用Graph DSL的流程结束后,你有这样的例子吗?@EmiCareOfCell44我也想在我的recover中包含这条消息。实际上,我正在寻找一个
recover
方法,该方法为我提供了导致流失败的值。为什么要从单个elment创建源呢?。您可以使用Graph DSL创建另一个流,并使用分区将错误重定向到另一个队列,因为我希望ACK严格发生在内部流结束之后。但也许它会发生在使用Graph DSL的流程结束后,你有这样的例子吗?@EmiCareOfCell44我也想在我的recover中包含这条消息。实际上,我正在寻找一种
recover
方法,它给我一个使流失败的值。