Flow.delayWith allows custom delay for each element. (#25000)

This commit is contained in:
Jean-Baptiste Giraudeau 2019-11-27 17:30:56 +01:00 committed by Johan Andrén
parent db141d0373
commit 6d893fb571
12 changed files with 500 additions and 44 deletions

View file

@ -16,6 +16,7 @@ import scala.annotation.unchecked.uncheckedVariance
import scala.concurrent.duration.FiniteDuration
import java.util.Comparator
import java.util.concurrent.CompletionStage
import java.util.function.Supplier
import com.github.ghik.silencer.silent
@ -883,6 +884,42 @@ class SubSource[Out, Mat](
def delay(of: java.time.Duration, strategy: DelayOverflowStrategy): SubSource[Out, Mat] =
delay(of.asScala, strategy)
/**
* Shifts elements emission in time by an amount individually determined through delay strategy a specified amount.
* It allows to store elements in internal buffer while waiting for next element to be emitted. Depending on the defined
* [[akka.stream.DelayOverflowStrategy]] it might drop elements or backpressure the upstream if
* there is no space available in the buffer.
*
* It determines delay for each ongoing element invoking `DelayStrategy.nextDelay(elem: T): FiniteDuration`.
*
* Note that elements are not re-ordered: if an element is given a delay much shorter than its predecessor,
* it will still have to wait for the preceding element before being emitted.
* It is also important to notice that [[DelayStrategy]] can be stateful.
*
* Delay precision is 10ms to avoid unnecessary timer scheduling cycles.
*
* Internal buffer has default capacity 16. You can set buffer size by calling `addAttributes(inputBuffer)`
*
* '''Emits when''' there is a pending element in the buffer and configured time for this element elapsed
* * EmitEarly - strategy do not wait to emit element if buffer is full
*
* '''Backpressures when''' depending on OverflowStrategy
* * Backpressure - backpressures when buffer is full
* * DropHead, DropTail, DropBuffer - never backpressures
* * Fail - fails the stream if buffer gets full
*
* '''Completes when''' upstream completes and buffered elements have been drained
*
* '''Cancels when''' downstream cancels
*
* @param delayStrategySupplier creates new [[DelayStrategy]] object for each materialization
* @param overFlowStrategy Strategy that is used when incoming elements cannot fit inside the buffer
*/
def delayWith(
delayStrategySupplier: Supplier[DelayStrategy[Out]],
overFlowStrategy: DelayOverflowStrategy): SubSource[Out, Mat] =
new SubSource(delegate.delayWith(() => DelayStrategy.asScala(delayStrategySupplier.get), overFlowStrategy))
/**
* Recover allows to send last element on failure and gracefully complete the stream
* Since the underlying failure signal onError arrives out-of-band, it might jump over existing elements.