time
This is a reference guide to the time family of operators. It describes:
- the behaviour of
sleep,delayBy,fixedDelay,awakeDelay,fixedRate,awakeEvery,spacedandmeteredand theirstartImmediatelyvariants.
- How each operator propagates chunks.
As the time family of operators have normal error propagation and finalizer handling, these are not described.
Behaviour
The time family of operators manipulate time by introducing delays. When pulled on, an operator delays for a certain length of time before outputting an element.
Operators are distinguished by:
- Whether they calculate the delay using the time of the pull or the time of the last outputted element. The
fixedDelayfamily of operators calculate delays using the time of the pull, whereasfixedRateoperators calculate delays using the time of the last outputted element.
- Whether they operate on an input stream, or construct a stream.
delayBy,spacedandmeteredoperate on an input stream, butfixedTate,fixedRate,awakeDelayandawakeEveryconstruct a stream.
- Whether they output a unit value
()or the elapsed time. Operators prefixed byfixedoutput a unit value, but operators prefixed byawakeoutput the elapsed time.
This is summarized in the table below.
| output value | delay using pull time | delay using output time |
|---|---|---|
| unit | fixedDelay |
fixedRate |
| elapsed time | awakeDelay |
awakeEvery |
| input value | spaced |
metered |
sleep
The sleep operator sleeps for a given amount of time before outputting a single unit value(). When pulled on, it waits for the given time to elapse before outputting the unit value (). The stream is then done.
delayBy
The delayBy operator sleeps for a given amount of time before pulling on its input stream.
In the following example, the input stream of characters is delayed by one second. When the resulting stream is pulled on, one second elapses before delayBy pulls on the input stream. The input stream is then pulled on as normal.
fixedDelay
The fixedDelay operator constructs a stream that repeatedly sleeps for a given amount of time.
Each time it is pulled on, it waits for the given time to elapse before outputting an element.
Stream.fixedDelay(n) is equivalent to Stream.sleep(n).repeat.
Slow element evaluation
The fixedDelay operator sleeps for the given amount of time, regardless of the time elapsed since its last output.
This is shown in the following example. The resulting stream is operated on by evalMap(_ => IO.sleep(2.seconds)). When fixedDelay outputs an element, there is a delay of two seconds before it is next pulled on. This does not affect the time that fixedDelay sleeps for: after it is pulled on, it still delays for one second.
awakeDelay
The awakeDelay operator is similar to fixedDelay, but outputs the elapsed time.
It sleeps for a given amount of time before outputting a duration, then repeats infinitely. The duration corresponds to the elapsed time since the resulting stream was first pulled on.
fixedRate
The fixedRate operator constructs a stream that outputs the unit value () at most every given time period.
Instant element evaluation
The following example constructs a stream that outputs () every second.
Note that when output evaluation is instantaneous, the fixedRate operator behaves similarly to fixedDelay.
Fast element evaluation
When pulled on, the fixedRate operator accounts for the time elapsed since its last output.
If the elapsed time is shorter than the given time period, fixedRate sleeps for the remainder of the period.
In the following example, fixedRate constructs a stream that outputs an element at most every three seconds.
The resulting stream is operated on by evalMap(_ => IO.sleep(1.second)). This introduces a delay of one second between the output and pull of fixedRate.
Note that the second time fixedDelay is pulled on, it delays by only two seconds. This ensures that the time elapsed between elements is the given rate of three seconds.
Slow element evaluation
If the elapsed time is longer than the given time period, fixedRate outputs an element immediately.
In the following example, fixedRate constructs a stream that outputs at most every one second. The resulting stream is operated on by evalMap(_ => IO.sleep(2.seconds)). This introduces a two second delay between the output and pull of fixedRate.
Note that when the fixedRate operator is pulled on for the second time, it outputs () immediately. This is because over one second has passed since it previously outputted an element.
Damping
The fixedRate operator is damped. It will only output a single element, no matter the length of the elapsed time.
In the following example, fixedRate is used to construct a stream that outputs at most every two seconds. The resulting stream is operated on by evalMap, which introduces a delay of five seconds before outputting the first element. All remaining elements are outputted immediately.
By delaying for five seconds, over two periods have elapsed since the last output. The third unit value is still delayed.
This ensures that fixedRate outputs elements at as close as possible to the given time period. Elements are outputted at 2s, 5s, and 6s.
Undamped
The fixedRate operator accepts a second dampen parameter. If it is set to false, the operator will output as many elements as periods that have elapsed.
The following example constructs the same stream as above, but dampen is set to false.
Note that the third time fixedRate is pulled on, () is outputted immediately. Because over two periods have elapsed since the last output, two unit values are outputted immediately.
Elements are outputted at 2s, 5s, 5s and 6s.
fixedRateStartImmediately
The fixedRateStartImmediately operator is similar to fixedRate. It outputs elements at most every given time period. Unlike fixedRate, it outputs its first value without a delay.
awakeEvery
The awakeEvery operator is similar to fixedRate. It outputs a duration value at most every given time period. The duration corresponds to the time elapsed since the stream was first pulled on.
spaced
The spaced operator delays by a given time period before pulling on its input stream. It does not account for the time elapsed since its last output.
Note that spaced pulls on its input stream immediately.
metered
The metered operator pulls on its input stream at most every given time period. When pulled on, it awaits until the given time period has elapsed since its last output before pulling on its input stream.
It has similar behaviour to fixedRate on slow output or input evaluation.
Instant evaluation
If the input stream outputs elements instantly, and the resulting stream is pulled on directly after its outputs, then metered delays by the given time period.
Note that it behaves exactly as spaced.
Slow output evaluation
There may be a delay between the resulting stream outputting an element and being pulled on. In this case, metered behaves as fixedRate and accounts for the time elapsed since its last output.
Slow input stream evaluation
Similarly, there may be a delay between the input stream being pulled on and outputting an element. metered behaves accounts for the time elapsed since its last output.
meteredStartImmediately
The meteredStartImmediately operator is similar to metered, however pulls on its input stream immediately when it is first pulled on.
Chunk propagation
By necessity, operators that introduce time delays output singleton chunks.
The fixedRate and fixedDelay operators output singleton chunks of the unit value (). The awakeDelay and awakeEvery operators output singleton chunks of the elapsed time.
delayBy
The delayBy operator preserves the chunks of its input stream.
In the following example, the input stream of a single chunk of characters [a, b] is delayed by one second. The resulting stream outputs the same chunk of characters.
spaced
The spaced operator outputs singleton chunks.
In the following example, the input stream outputs a single chunk of characters [a, b]. When pulled on, the resulting stream outputs a singleton chunk of [a], then a singleton chunk of [b].
metered
The metered operator also outputs singleton chunks.
In the following example, the input stream outputs a single chunk of characters [a, b]. When pulled on, the resulting stream outputs a singleton chunk of [a], then a singleton chunk of [b].