SoFunction
Updated on 2025-03-05

Golang function retry mechanism implementation code

Preface

When writing applications, you sometimes encounter some short-term errors, such as network requests, service link terminal failures, etc. These errors may cause function execution to fail.
However, if the execution may be successful later, then you need to try again in some business scenarios. The concept of retry is very simple, so I won't explain it too much here

Recently, I'm also switching to the golang language. The retry mechanism can be used to practice. The retry function generally needs to support the following parameters.

  • execFunc: a retry function that needs to be executed
  • interval: the interval for retry
  • attempts: the number of attempts
  • conditionMode: retry condition mode, error and bool mode (this parameter is used to control the passed execution function return value type detection

Code

package retryimpl
import (
	"fmt"
	"time"
)
// RetryOptionV2 configuration option functiontype RetryOptionV2 func(retry *RetryV2)
// RetryFunc Retry function without return valuetype RetryFunc func() error
// RetryFuncWithData Retry function with return valuetype RetryFuncWithData func() (any, error)
// RetryV2 retry classtype RetryV2 struct {
	interval  // The interval between retry	attempts int           // Number of retry}
// NewRetryV2 constructorfunc NewRetryV2(opts ...RetryOptionV2) *RetryV2 {
	retry := RetryV2{
		interval: DefaultInterval,
		attempts: DefaultAttempts,
	}
	for _, opt := range opts {
		opt(&retry)
	}
	return &retry
}
// WithIntervalV2 retry interval configurationfunc WithIntervalV2(interval ) RetryOptionV2 {
	return func(retry *RetryV2) {
		 = interval
	}
}
// WithAttemptsV2 Retry timesfunc WithAttemptsV2(attempts int) RetryOptionV2 {
	return func(retry *RetryV2) {
		 = attempts
	}
}
// DoV2 exposes the execution functionfunc (r *RetryV2) DoV2(executeFunc RetryFunc) error {
	("[Retry.DoV2] begin execute func...")
	retryFuncWithData := func() (any, error) {
		return nil, executeFunc()
	}
	_, err := r.DoV2WithData(retryFuncWithData)
	return err
}
// DoV2WithData Exposed to the outside can return datafunc (r *RetryV2) DoV2WithData(execWithDataFunc RetryFuncWithData) (any, error) {
	("[Retry.DoV2WithData] begin execute func...")
	n := 0
	for n <  {
		res, err := execWithDataFunc()
		if err == nil {
			return res, nil
		}
		n++
		()
	}
	return nil, nil
}

Test verification

package retryimpl
import (
	"errors"
	"fmt"
	"testing"
	"time"
)
// TestRetryV2_DoFunc
func TestRetryV2_DoFunc(t *) {
	testSuites := []struct {
		exceptExecCount int
		actualExecCount int
	}{
		{exceptExecCount: 3, actualExecCount: 0},
		{exceptExecCount: 1, actualExecCount: 1},
	}
	for _, testSuite := range testSuites {
		retry := NewRetryV2(
			WithAttemptsV2(),
			WithIntervalV2(1*),
		)
		err := retry.DoV2(func() error {
			("[TestRetry_DoFuncBoolMode] was called ...")
			if  == 1 {
				return nil
			}
			++
			return ("raise error")
		})
		if err != nil {
			("[TestRetryV2_DoFunc] retyr.DoV2 execute failed and err:%+v", err)
			continue
		}
		if  !=  {
			("[TestRetryV2_DoFunc] got actualExecCount:%v != exceptExecCount:%v", , )
		}
	}
}
// TestRetryV2_DoFuncWithData
func TestRetryV2_DoFuncWithData(t *) {
	testSuites := []struct {
		exceptExecCount int
		resMessage      string
	}{
		{exceptExecCount: 3, resMessage: "fail"},
		{exceptExecCount: 1, resMessage: "ok"},
	}
	for _, testSuite := range testSuites {
		retry := NewRetryV2(
			WithAttemptsV2(),
			WithIntervalV2(1*),
		)
		res, err := retry.DoV2WithData(func() (any, error) {
			("[TestRetryV2_DoFuncWithData] DoV2WithData was called ...")
			if  == 1 {
				return , nil
			}
			return , ("raise error")
		})
		if err != nil {
			("[TestRetryV2_DoFuncWithData] retyr.DoV2 execute failed and err:%+v", err)
			continue
		}
		if val, ok := res.(string); ok && val !=  {
			("[TestRetryV2_DoFuncWithData] got unexcept result:%+v", val)
			continue
		}
		("[TestRetryV2_DoFuncWithData] got result:%+v", )
	}
}

refer to:GitCode - Developer's code home

This is the end of this article about the implementation of the Golang function retry mechanism. For more related content of the Golang retry mechanism, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!