I have encountered something that is against my expectations in the sliding
window of Akka streams 2.0-M2. Before I log an actual bug, could someone
read along and check that this is actually a bug or a case of RTFM-better,
or simply something subjective?
The docs for Flow.sliding say:
Apply a sliding window over the stream and return the windows as groups of
elements, with the last group possibly smaller than requested due to
end-of-stream.
This describes a fairly clear behaviour, which I interpreted as follows:
sliding has a window-size parameter and an increment/step parameter. The
latter is leading, and the window essentially allows you to 'peek ahead' a
given number of values. If no more values are available because the stream
terminates, the window may be smaller than specified. What I observe
however is a wider set of behaviours. I will specify examples using count,
window and increment as if supplied to the following function:
def test(count: Int, window: Int, step: Int): Future[Seq[Seq[Int]]] =
Source(Stream.from(0))
.take(count)
.sliding(window, step)
.runFold(Seq.empty[Seq[Int]]) { case (total, slice) =>
total :+ slice
}
i.e. it dumps all windows (over non-negative integers) in chronological
order. Here are some calls with results (non-arbitrary, somewhat minimised
examples exhausting the various behaviours I found)
1. test(3, 1, 1) = List(Vector(0), Vector(1), Vector(2)) - Good so far!
2. test(3, 2, 2) = List(Vector(0, 1), Vector(2)) - You got it! :)
3. test(3, 2, 1) = List(Vector(0, 1), Vector(1, 2)) - Really? My
expectation: List(Vector(0, 1), Vector(1, 2), Vector(2))
4. test(10, 2, 6) = List(Vector(0, 1), Vector(6, 7), Vector(6, 7, 8, 9))
- Wait, what? My expectation: List(Vector(0, 1), Vector(6, 7))
Now 1 and 2 are clearly as documented, and in line with what I expect.
Increment gets respected, window-size may be reduced if no more elements
are available. In scenario 3 however, a different behaviour pops up: in
general it seems to favour respecting window-size over increment in many
cases (my closest approximation of when it happens: window < count && step
= 1)
If your use case is like mine, this is a problem. I simply wanted a 1-1
mapping between elements from source to sink, but modify each value
according to some function that can take the next value in the stream as
well. Given that you only propagate the current value on the stream, and
not the one 'peeked ahead' at (to prevent duplicate values in your output),
you will lose your final value in finite streams. I am less certain this is
a bug, it looks like this 'fitting windows over a stream with given steps'
may be useful in some cases, and therefore more of a design choice, I'm
interested to hear what you think.
I also encountered case 4, however, when trying to figure out what sliding
actually does. This one seems clearly wrong to me, neither increment (we
see 6 two times), nor window-size gets respected, neither in a documented
or intuitive way. (informally, it seems to happen when the next step
surpasses the last value on the stream, but there were still values on the
stream that weren't consumed in the previous window) I don't file it as a
bug as of yet though, because I'm still interested in what you find the
correct behaviour for this case.
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ:
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.