我是Akka Streams的新手,我想知道如何实现某种中流验证。例如:
FileIO
.fromPath(file)
.via(Framing.delimiter(...)
.map(_.utf8String)
.map(_.split("\t", -1))
.validate(arr => arr.length == 10) // or similar
...
我认为这种情况非常普遍,必须有一个预定义的功能来动态验证流。但是,我无法找到任何相关信息。我在错误的轨道上,验证是不应该在Akka Streams 这样的事情吗?
在我的特定场景中,我逐行处理文件。如果只有一行是无效的,则继续没有意义,应该中止处理。
答案 0 :(得分:3)
我可能会创建一个表示约束的类型,然后你可以在创建该类型的实例时执行断言,并知道下游已经应用了哪些约束。
示例:
{{1}}
答案 1 :(得分:2)
您可以使用.takeWhile
。这将处理无效项目之前的所有元素,而不处理其后的任何项目。
FileIO
.fromPath(file)
.via(Framing.delimiter(...)
.map(_.utf8String)
.map(_.split("\t", -1))
.takeWhile(arr => arr.length == 10)
...
答案 2 :(得分:1)
我同意@Stephen takeWhile
是你需要的。如果希望将失败的元素传递到下游,可以将inclusive
标志设置为true来使用它。
此外,如果您想使您的信息流最具表现力,您可以让验证流产生Either[ValidationError, String]
。
下面的例子有点笨重,我更喜欢使用graphDSL和partition
,但希望你能得到这个想法。
val errorSink: Sink[TooManyElements, _] = ???
val sink: Sink[Array[String], _] = ???
FileIO
.fromPath(file)
.via(Framing.delimiter(...))
.map(_.utf8String.split("\t", -1))
.map{
case arr if arr.length > 10 ⇒ Left(TooManyElements(arr.length))
case arr ⇒ Right(arr)
}
.takeWhile(_.isRight, inclusive = true)
.alsoTo(Flow[Either[TooManyElements, Array[String]]].filter(_.isLeft).to(errorSink)
.filter(_.isRight)
.to(sink)