Interaction between zipLatest and an empty source


I’ve got the following snippet:

def eval[A](stream: Source[A, NotUsed]): Seq[A] =
  Await.result(stream.runWith(Sink.seq), 10.seconds)

println(eval(Source.single(3) zipLatest Source.empty)) // 1
println(eval(Source.single(3) zipLatest Source(List()))) // 2
println(eval(Source(List()) zipLatest Source(List()))) // 3

When executed:

  • the first zipLatest completes, printing an empty Vector.
  • the second one times out, even though Source(List()) individually does complete.
  • the third one completes again.

According to the docs zipLatest should complete when any upstream completes. How come it does complete for Source.empty but not for some uses of Source(List())? Is this the intended behaviour?

It looks like a bug. The Source(List()) is implemented as Source.single(iterable).mapConcat(identity) and that is not the same as Source.empty, which trips up zipLatest. This should definitely be fixed. Could you create an issue on the issue tracker where we could discuss the approach to fix this?

Ticket in the issue tracker: