diff --git a/README.md b/README.md index cbb3307..a46707d 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Handy misc tools for go development * Structs - Set/Get helpers to write/read random fields from structs by their string names * TimeId - a set of helpers to work with Date/Time as a timeID in YYDDMM format * URI - a set of helpers duplicating functionality of JS's encodeuricomponent/decodeuricomponent and others +* Retry - simple retry wrapper, supports Before and After retry ## Installation diff --git a/retry/retry.go b/retry/retry.go new file mode 100644 index 0000000..2c8e4a5 --- /dev/null +++ b/retry/retry.go @@ -0,0 +1,33 @@ +package retry + +type RetryOperation struct { + BeforeRetryCallback func(error) + AfterRetryCallback func(error) + FinalError error +} + +// Builds new retryable operation +func New() *RetryOperation { + return &RetryOperation{dummyCallback, dummyCallback, nil} +} + +// Setup custom action before +func (rop *RetryOperation) BeforeRetry(before func(error)) { + rop.BeforeRetryCallback = before +} + +// Setup custom action after +func (rop *RetryOperation) AfterRetry(after func(error)) { + rop.AfterRetryCallback = after +} + +// Execute operation with retry +func (rop *RetryOperation) Do(mainFunc func() error) { + if err := mainFunc(); err != nil { + rop.BeforeRetryCallback(err) + rop.FinalError = mainFunc() + rop.AfterRetryCallback(err) + } +} + +func dummyCallback(err error) {} diff --git a/retry/retry_suite_test.go b/retry/retry_suite_test.go new file mode 100644 index 0000000..322611d --- /dev/null +++ b/retry/retry_suite_test.go @@ -0,0 +1,13 @@ +package retry_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestRetry(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Retry Suite") +} diff --git a/retry/retry_test.go b/retry/retry_test.go new file mode 100644 index 0000000..051ba2c --- /dev/null +++ b/retry/retry_test.go @@ -0,0 +1,55 @@ +package retry_test + +import ( + "fmt" + + . "github.com/cthulhu/go-steun/retry" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Retry", func() { + operation := New() + var Retried bool + var RetriedWithError error + BeforeEach(func() { + RetriedWithError = nil + Retried = false + }) + Context("No error", func() { + It("excutes only main function", func() { + operation.BeforeRetry(func(err error) { + Retried = true + RetriedWithError = err + }) + operation.Do(func() error { + return nil + }) + Expect(RetriedWithError).To(BeNil()) + Expect(Retried).To(BeFalse()) + }) + }) + Context("With error", func() { + It("excutes only main function", func() { + operation.BeforeRetry(func(err error) { + Retried = true + RetriedWithError = err + }) + operation.Do(func() error { + return fmt.Errorf("Generic Error") + }) + Expect(RetriedWithError).To(HaveOccurred()) + Expect(Retried).To(BeTrue()) + }) + }) + Context("With error no retry", func() { + It("excutes only main function", func() { + operation.Do(func() error { + return fmt.Errorf("Generic Error") + }) + Expect(RetriedWithError).To(HaveOccurred()) + Expect(Retried).To(BeTrue()) + }) + }) +})