juju/retry take 2 - looping

Katherine Cox-Buday katherine.cox-buday at canonical.com
Tue Oct 25 21:30:00 UTC 2016


Tim Penhey <tim.penhey at canonical.com> writes:

> The rationale behind that is to make the the library handle the 80%
> case easily. The main reason of passing the error into Next is so you
> don't have to do the check and explicit break within the loop.

I will argue here that this goes against a core principle of Go which is to be informed and care about your error path.

> Sure, but this could be trivially handled by assigning something to
> err (consider if we made a public error in the retry package for
> this):
>
> var result Foo
> var err error
> for loop := retry.Loop(spec); loop.Next(err); {
>    result, err = SomeFunc(blah)
>    if err == nil && resultNotGoodEnough(result) {
>      err = retry.ErrTryAgain
>    }
> }
> if err != nil {
>    // what ever
> }
> // continue using result

I think this is a hint that this is the wrong approach. The edge-cases begin showing the cracks in the abstraction and end up making the code more complex. Consider your example instead of:

var finalResult Foo
for loop := retry.Loop(spec); loop.Next(); {
    result, err := SomeFunc(blah)
    if err != nil || resultNotGoodEnough(result) {
        continue
    }

	finalResult = result
    break
}

There are no special errors, no mixing of concerns, just a boring imperative loop. It works like any other loop written in Go.

-- 
Katherine



More information about the Juju-dev mailing list