safwank / ElixirRetry

Simple Elixir macros for linear retry, exponential backoff and wait with composable delays
Other
441 stars 32 forks source link

Bug: expiry/3 evaluates the expiry time at time of stream definition #47

Closed jtrees closed 2 years ago

jtrees commented 2 years ago

expiry/3 can lead to some very confusing behaviour if you don't immediately run the stream.

Here's an example test (that currently fails) to demonstrate:

test "evaluates expiry at runtime of the stream, rather than execution time of expiry/3" do
  delay_stream =
    [50]
    |> Stream.cycle()
    |> expiry(75, 50)

  assert Enum.count(delay_stream, fn delay -> :timer.sleep(delay) end) == 2

  # If the expiry time is determined when `expiry/3` is executed, we will
  # already be past it (due to all the sleeps performed previously) and jump
  # out after the first run.
  assert Enum.count(delay_stream, fn delay -> :timer.sleep(delay) end) == 2
end

It would be much nicer if the stream could be re-used (kind of like a config value) instead.

safwank commented 2 years ago

Good catch. Completely agree that it violates the principle of least astonishment. Looking at the PR now.