-
Notifications
You must be signed in to change notification settings - Fork 154
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add Flow/Sink#foldWhile operator. (#1012)
- Loading branch information
Showing
23 changed files
with
551 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Sink.foldWhile | ||
|
||
Fold over emitted elements with a function, where each invocation will get the new element and the result from the previous fold invocation. | ||
|
||
@ref[Sink operators](../index.md#sink-operators) | ||
|
||
## Signature | ||
|
||
@apidoc[Sink.foldWhile](Sink$) { scala="#foldWhile%5BU%2C%20T%5D(zero%3A%20U)(p%3A%20U%20%3D%3E%20Boolean)(f%3A%20(U%2C%20T)%20%3D%3E%20U):org.apache.pekko.stream.scaladsl.Sink[T,scala.concurrent.Future[U]]" java="#foldWhile(java.lang.Object,org.apache.pekko.japi.function.Predicate,org.apache.pekko.japi.function.Function2)" } | ||
|
||
## Description | ||
|
||
A Sink that will invoke the given function for every received element, giving it its previous output (or the given zero value) | ||
and the element as input. | ||
|
||
Materializes into a @scala[`Future`] @java[`CompletionStage`] that will complete with the last state when the stream has completed, | ||
predicate p returns false, or completed with Failure if there is a failure signaled in the stream. | ||
|
||
This operator allows combining values into a result without a global mutable state by instead passing the state along | ||
between invocations. | ||
|
||
## Example | ||
|
||
`foldWhile` is typically used to 'fold up' the incoming values into an aggregate with a predicate. | ||
For example, you can use `foldWhile` to calculate the sum while some predicate is true. | ||
|
||
Scala | ||
: @@snip [FoldWhile.scala](/docs/src/test/scala/docs/stream/operators/sink/FoldWhile.scala) { #foldWhile } | ||
|
||
Java | ||
: @@snip [FoldWhile.java](/docs/src/test/java/jdocs/stream/operators/sink/FoldWhile.java) { #foldWhile } | ||
|
||
## Reactive Streams semantics | ||
|
||
@@@div { .callout } | ||
|
||
**cancels** never | ||
|
||
**backpressures** when the previous fold function invocation has not yet completed | ||
|
||
@@@ | ||
|
48 changes: 48 additions & 0 deletions
48
docs/src/main/paradox/stream/operators/Source-or-Flow/foldWhile.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# foldWhile | ||
|
||
Start with current value `zero` and then apply the current and next value to the given function. When upstream completes or the predicate `p` returns `false`, the current value is emitted downstream. | ||
|
||
@ref[Simple operators](../index.md#simple-operators) | ||
|
||
## Signature | ||
|
||
@apidoc[Source.foldWhile](Source) { scala="#foldWhile%5BT%5D(zero%3A%20T)(p%3A%20T%20%3D%3E%20Boolean)(f%3A%20(T%2C%20Out)%20%3D%3E%20T):FlowOps.this.Repr[T]" java="#foldWhile(java.lang.Object,org.apache.pekko.japi.function.Predicate,org.apache.pekko.japi.function.Function2)" } | ||
@apidoc[Flow.foldWhile](Flow) { scala="#foldWhile%5BT%5D(zero%3A%20T)(p%3A%20T%20%3D%3E%20Boolean)(f%3A%20(T%2C%20Out)%20%3D%3E%20T):FlowOps.this.Repr[T]" java="#foldWhile(java.lang.Object,org.apache.pekko.japi.function.Predicate,org.apache.pekko.japi.function.Function2)" } | ||
|
||
## Description | ||
|
||
Start with current value `zero` and then apply the current and next value to the given function. When upstream | ||
completes, the current value is emitted downstream. | ||
|
||
@@@ warning | ||
|
||
Note that the `zero` value must be immutable, because otherwise | ||
the same mutable instance would be shared across different threads | ||
when running the stream more than once. | ||
|
||
@@@ | ||
|
||
## Example | ||
|
||
`foldWhile` is typically used to 'fold up' the incoming values into an aggregate with a predicate. | ||
For example, you can use `foldWhile` to calculate the sum while some predicate is true. | ||
|
||
|
||
Scala | ||
: @@snip [FoldWhile.scala](/docs/src/test/scala/docs/stream/operators/sourceorflow/FoldWhile.scala) { #imports #foldWhile } | ||
|
||
Java | ||
: @@snip [FoldWhile.java](/docs/src/test/java/jdocs/stream/operators/flow/FoldWhile.java) { #foldWhile } | ||
|
||
## Reactive Streams semantics | ||
|
||
@@@div { .callout } | ||
|
||
**emits** when upstream completes | ||
|
||
**backpressures** when downstream backpressures | ||
|
||
**completes** when upstream completes | ||
|
||
@@@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
docs/src/test/java/jdocs/stream/operators/flow/FoldWhile.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package jdocs.stream.operators.flow; | ||
|
||
// #imports | ||
|
||
import org.apache.pekko.actor.ActorSystem; | ||
import org.apache.pekko.stream.javadsl.Source; | ||
|
||
// #imports | ||
|
||
public class FoldWhile { | ||
private static final ActorSystem system = null; | ||
|
||
private void foldWhileUsage() { | ||
// #foldWhile | ||
Source.range(1, 10) | ||
.foldWhile(0, acc -> acc < 10, Integer::sum) | ||
.runForeach(System.out::println, system); | ||
// Expect prints: | ||
// 100 | ||
// #foldWhile | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
docs/src/test/java/jdocs/stream/operators/sink/FoldWhile.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package jdocs.stream.operators.sink; | ||
|
||
import org.apache.pekko.actor.ActorSystem; | ||
import org.apache.pekko.stream.javadsl.Sink; | ||
import org.apache.pekko.stream.javadsl.Source; | ||
|
||
public class FoldWhile { | ||
private ActorSystem system = null; | ||
|
||
public void foldWhileUsage() throws Exception { | ||
// #foldWhile | ||
final int result = | ||
Source.range(1, 10) | ||
.runWith(Sink.foldWhile(0, acc -> acc < 10, Integer::sum), system) | ||
.toCompletableFuture() | ||
.get(); | ||
System.out.println(result); | ||
// Expect prints: | ||
// 10 | ||
// #foldWhile | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
docs/src/test/scala/docs/stream/operators/sink/FoldWhile.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package docs.stream.operators.sink | ||
|
||
import org.apache.pekko.actor.ActorSystem | ||
import org.apache.pekko.stream.scaladsl.{ Sink, Source } | ||
|
||
import scala.concurrent.duration.DurationInt | ||
import scala.concurrent.{ Await, ExecutionContextExecutor } | ||
|
||
class FoldWhile { | ||
implicit val system: ActorSystem = ??? | ||
implicit val ec: ExecutionContextExecutor = system.dispatcher | ||
|
||
// #foldWhile | ||
val r = Source(1 to 10) | ||
.runWith(Sink.foldWhile(0L)(_ < 10)(_ + _)) | ||
println(Await.result(r, 3.seconds)) | ||
// Expect prints: | ||
// 10 | ||
// #foldWhile | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
docs/src/test/scala/docs/stream/operators/sourceorflow/FoldWhile.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package docs.stream.operators.sourceorflow | ||
|
||
//#imports | ||
import org.apache.pekko | ||
import pekko.actor.ActorSystem | ||
import pekko.stream.scaladsl.Source | ||
|
||
//#imports | ||
object FoldWhile extends App { | ||
|
||
implicit val sys: ActorSystem = ActorSystem() | ||
|
||
// #foldWhile | ||
Source(1 to 10) | ||
.foldWhile(0)(_ < 10)(_ + _) | ||
.runForeach(println) | ||
// Expect prints: | ||
// 10 | ||
// #foldWhile | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.