How does a GenStage producer say it is done?

This is an oversimplified example, but I’m trying to figure out how to create a GenStage producer that can signal completion to GenStage.stream without causing the consuming process to exit.

Here’s my example (adapted from my doctest):

iex> {:ok, stage} = GenStage.from_enumerable(["Hello", "World"])
iex> GenStage.stream([stage]) |> Enum.to_list()
{"Hello", "World"}

… but this test fails with:

 ** (exit) exited in: GenStage.close_stream(%{})
     ** (EXIT) normal

What am I missing?

When it is done, it just terminates! If that’s expected, which is the case for finite stages, you set the cancel subscription option to transient:

 GenStage.stream([{stage, cancel: :transient}]) |> Enum.to_list()

I believe this is in the docs but, if it can be clearer, please send a PR!

Thanks, José, that makes sense.

I will see if I can find a way to make this more obvious. Spent a fair amount of time reading docs and didn’t get to that conclusion.