Reputation: 19342
I am launching two concurrent execution paths (a.k.a. goroutines) to perform two jobs
const Retries = 10
wg.Add(2)
go func() {
for i := 0; i < Retries; i++ {
retVal1, err1 = doSomeWork()
if err1 != nil {
fmt.Printf("WARNING: Error job in attempt no %d: %s - retrying...\n", i+1, err1)
continue
} else {
break
}
}
if err1 != nil {
log.Fatalf("ERROR job %s\n", err1)
}
wg.Done()
}()
go func() {
for i := 0; i < Retries; i++ {
retVal2, err2 = doSomeWork()
if err2 != nil {
fmt.Printf("WARNING: Error job in attempt no %d: %s - retrying...\n", i+1, err2)
continue
} else {
break
}
}
if err2 != nil {
log.Fatalf("ERROR job %s\n", err2)
}
wg.Done()
}()
wg.Wait()
My question is (apart from importing some third-party retry library) whether there is more go-idiomatic way to structure the above code? Would a channel / select approach be more go-centric?
Upvotes: 1
Views: 1195
Reputation: 22154
Your code is not that bad. Using channels would be an overkill.
I would write it this way which is slightly lighter.
const maxRetries int = 3
go func() {
var retries int
for {
retVal1, err1 = doSomeWork()
if err1 == nil {
break
}
retries++
if retries == maxRetries {
log.Fatalf("ERROR job %s\n", err1)
}
fmt.Printf("WARNING: Error job in attempt no %d: %s - retrying...\n", retries, err1)
}
wg.Done()
}()
Upvotes: 1