Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow constant backoff of zero seconds. #24

Closed
wants to merge 1 commit into from

Conversation

jlevitt
Copy link

@jlevitt jlevitt commented Feb 9, 2024

Seems like a valid use case to immediately retry with zero dely. The comments of this function seem to indicate that it should be less than zero as well.

Copy link
Owner

@sethvargo sethvargo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the value in using this library at all (over a for loop) in that case? The overhead of running through the cancellation checks and unwrapping is likely a few nanoseconds anyway.

@jlevitt
Copy link
Author

jlevitt commented Feb 12, 2024

Using this library makes the code easier to read. I actually found the library because I'm refactoring a for loop retry that is hard to reason about into a much simpler block of code using the library 😃

@sethvargo
Copy link
Owner

My concern with zero is that it's no different from a for loop - what are you trying to do:

for {
  if thing(); err != nil {
    if errors.Is(err, MyThing) {
      continue // same as retry.RetryableError
    }
  }

  break
}

@jlevitt
Copy link
Author

jlevitt commented Feb 12, 2024

Previously, inside the loop was a bunch of complex error handling for multiple different types of errors. Using the library makes it easy to clearly delineate which are retryable and which aren't and separate them visually. It makes it easy to break down the problem in to understandable chunks.

@sethvargo
Copy link
Owner

Previously, inside the loop was a bunch of complex error handling for multiple different types of errors. Using the library makes it easy to clearly delineate which are retryable and which aren't and separate them visually. It makes it easy to break down the problem in to understandable chunks.

Can you share the code? If you aren't doing something with complex backoffs, maximum retries, etc, then it's almost certainly easier to just use a loop. The value of this library is in having many different invariants for determining retries and handling sleeps with cancelation. If you aren't sleeping, there's really no value in using this library.

@jlevitt
Copy link
Author

jlevitt commented Feb 12, 2024

I don't think I'm allowed to share the code, but I can say that after refactoring to use the library the critical section went from 51 lines to 30 and is much easier to read IMO.

If you aren't sleeping, there's really no value in using this library.

I disagree, readability is extremely valuable and using this library improves it by allowing me to describe the retry mechanism using functions with clear names and obvious behavior. It also makes it easier to separate the retryable condition from the non-retryable. I highly value readability and if I need a few extra clock cycles to improve it, I'm ok with that.

IMO return retry.RetryableError(respErr) is much clearer than a continue that's nestled among multiple other error handling blocks. If you still disagree, I won't press the point. I can just use time.Nanosecond.

@sethvargo
Copy link
Owner

If you'd like, you can create your own Backoffer (it's just an interface), but I don't want to support this in the core library because it's far too easy to misconfigure and end up in an unescapable hot loop.

var NoBackoff = retry.BackoffFunc(func() (time.Duration, bool) {
  return 0, false
})

@sethvargo sethvargo closed this Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants