New Upstream Release - golang-gopkg-eapache-go-resiliency.v1
Ready changes
Summary
Merged new upstream version: 1.3.0 (was: 1.2.0).
Resulting package
Built on 2022-12-14T15:01 (took 3m30s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases golang-gopkg-eapache-go-resiliency.v1-dev
Lintian Result
Diff
diff --git a/.github/workflows/golang-ci.yml b/.github/workflows/golang-ci.yml
new file mode 100644
index 0000000..b2d5179
--- /dev/null
+++ b/.github/workflows/golang-ci.yml
@@ -0,0 +1,24 @@
+name: Golang CI
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go-version: [1.13, 1.18]
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Set up Go
+ uses: actions/setup-go@v3
+ with:
+ go-version: ${{ matrix.go-version }}
+
+ - name: Build
+ run: go build -v ./...
+
+ - name: Test
+ run: go test -v ./...
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 21008c3..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-language: go
-
-go:
- - 1.7
- - 1.12
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66e1857..f0d44b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,23 @@
# Changelog
-#### Version 1.2.0 (2019-06-14)
+*Note: I will occasionally bump the minimum required Golang version without
+bumping the major version of this package, which violates the official Golang
+packaging convention around breaking changes. Typically the versions being
+dropped are multiple years old and long unsupported.*
+
+#### Version 1.3.0 (2022-06-27)
-*Note: This release requires Golang at least 1.7, which is higher than the
-previous release. All the versions being dropped are multiple years old and no
-longer supported upstream, so I'm not counting this as a breaking change.*
+ - Increased minimum Golang version to 1.13.
+ - Fix a goroutine leak in `Deadline.Run()` on `ErrTimeOut`.
+ - Add a `go.mod` file to conform to more recent Golang version standards.
+ - Use `errors.Is` when classifying errors for the `Retrier` (thanks to Taufik
+ Rama).
+ - Add implementation of `LimitedExponentialBackoff` for the `Retrier` (thanks
+ to tukeJonny).
+
+#### Version 1.2.0 (2019-06-14)
+ - Increased minimum Golang version to 1.7.
- Add `RunCtx` method on `Retrier` to support running with a context.
- Ensure the `Retrier`'s use of random numbers is concurrency-safe.
- Bump CI to ensure we support newer Golang versions.
diff --git a/README.md b/README.md
index 0a0d701..86368ec 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
go-resiliency
=============
-[![Build Status](https://travis-ci.org/eapache/go-resiliency.svg?branch=master)](https://travis-ci.org/eapache/go-resiliency)
+[![Golang CI](https://github.com/eapache/go-resiliency/actions/workflows/golang-ci.yml/badge.svg)](https://github.com/eapache/go-resiliency/actions/workflows/golang-ci.yml)
[![GoDoc](https://godoc.org/github.com/eapache/go-resiliency?status.svg)](https://godoc.org/github.com/eapache/go-resiliency)
[![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-active-blue.svg)](https://eapache.github.io/conduct.html)
@@ -16,6 +16,7 @@ Currently implemented patterns include:
- batching (in the `batcher` directory)
- retriable (in the `retrier` directory)
-Follows semantic versioning using https://gopkg.in/ - import from
-[`gopkg.in/eapache/go-resiliency.v1`](https://gopkg.in/eapache/go-resiliency.v1)
-for guaranteed API stability.
+*Note: I will occasionally bump the minimum required Golang version without
+bumping the major version of this package, which violates the official Golang
+packaging convention around breaking changes. Typically the versions being
+dropped are multiple years old and long unsupported.*
diff --git a/deadline/deadline.go b/deadline/deadline.go
index 3a6dfb0..c97fd86 100644
--- a/deadline/deadline.go
+++ b/deadline/deadline.go
@@ -32,7 +32,11 @@ func (d *Deadline) Run(work func(<-chan struct{}) error) error {
stopper := make(chan struct{})
go func() {
- result <- work(stopper)
+ value := work(stopper)
+ select {
+ case result <- value:
+ case <-stopper:
+ }
}()
select {
diff --git a/debian/changelog b/debian/changelog
index fd940f0..f139dc5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+golang-gopkg-eapache-go-resiliency.v1 (1.3.0-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Wed, 14 Dec 2022 14:58:46 -0000
+
golang-gopkg-eapache-go-resiliency.v1 (1.2.0-1) unstable; urgency=medium
[ Debian Janitor ]
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..11f4ca3
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module github.com/eapache/go-resiliency
+
+go 1.13
diff --git a/retrier/backoffs.go b/retrier/backoffs.go
index faf6f8c..cf04f60 100644
--- a/retrier/backoffs.go
+++ b/retrier/backoffs.go
@@ -22,3 +22,20 @@ func ExponentialBackoff(n int, initialAmount time.Duration) []time.Duration {
}
return ret
}
+
+// LimitedExponentialBackoff generates a simple back-off strategy of retrying 'n' times, and doubling the amount of
+// time waited after each one.
+// If back-off reaches `limitAmount` , thereafter back-off will be filled with `limitAmount` .
+func LimitedExponentialBackoff(n int, initialAmount time.Duration, limitAmount time.Duration) []time.Duration {
+ ret := make([]time.Duration, n)
+ next := initialAmount
+ for i := range ret {
+ if next < limitAmount {
+ ret[i] = next
+ next *= 2
+ } else {
+ ret[i] = limitAmount
+ }
+ }
+ return ret
+}
diff --git a/retrier/backoffs_test.go b/retrier/backoffs_test.go
index 1168adf..ca323b8 100644
--- a/retrier/backoffs_test.go
+++ b/retrier/backoffs_test.go
@@ -53,3 +53,33 @@ func TestExponentialBackoff(t *testing.T) {
t.Error("incorrect value")
}
}
+
+func TestLimitedExponentialBackoff(t *testing.T) {
+ b := LimitedExponentialBackoff(1, 10*time.Millisecond, 11*time.Millisecond)
+ if len(b) != 1 {
+ t.Error("incorrect length")
+ }
+ if b[0] != 10*time.Millisecond {
+ t.Error("incorrect value")
+ }
+
+ b = LimitedExponentialBackoff(5, 1*time.Minute, 4*time.Minute)
+ if len(b) != 5 {
+ t.Error("incorrect length")
+ }
+ if b[0] != 1*time.Minute {
+ t.Error("incorrect value")
+ }
+ if b[1] != 2*time.Minute {
+ t.Error("incorrect value")
+ }
+ if b[2] != 4*time.Minute {
+ t.Error("incorrect value")
+ }
+ if b[3] != 4*time.Minute {
+ t.Error("incorrect value")
+ }
+ if b[4] != 4*time.Minute {
+ t.Error("incorrect value")
+ }
+}
diff --git a/retrier/classifier.go b/retrier/classifier.go
index 7dd71c7..20d5a73 100644
--- a/retrier/classifier.go
+++ b/retrier/classifier.go
@@ -1,5 +1,7 @@
package retrier
+import "errors"
+
// Action is the type returned by a Classifier to indicate how the Retrier should proceed.
type Action int
@@ -38,7 +40,7 @@ func (list WhitelistClassifier) Classify(err error) Action {
}
for _, pass := range list {
- if err == pass {
+ if errors.Is(err, pass) {
return Retry
}
}
@@ -57,7 +59,7 @@ func (list BlacklistClassifier) Classify(err error) Action {
}
for _, pass := range list {
- if err == pass {
+ if errors.Is(err, pass) {
return Fail
}
}
diff --git a/retrier/classifier_test.go b/retrier/classifier_test.go
index 953102f..46b5ce0 100644
--- a/retrier/classifier_test.go
+++ b/retrier/classifier_test.go
@@ -29,6 +29,18 @@ func TestDefaultClassifier(t *testing.T) {
}
}
+type wrappedErr struct {
+ error
+}
+
+func (w wrappedErr) Error() string {
+ return "there's an error happening during X: " + w.Error()
+}
+
+func (w wrappedErr) Unwrap() error {
+ return w.error
+}
+
func TestWhitelistClassifier(t *testing.T) {
c := WhitelistClassifier{errFoo, errBar}
@@ -45,6 +57,16 @@ func TestWhitelistClassifier(t *testing.T) {
if c.Classify(errBaz) != Fail {
t.Error("whitelist misclassified baz")
}
+
+ if c.Classify(wrappedErr{error: errFoo}) != Retry {
+ t.Error("whitelist misclassified foo")
+ }
+ if c.Classify(wrappedErr{error: errBar}) != Retry {
+ t.Error("whitelist misclassified bar")
+ }
+ if c.Classify(wrappedErr{error: errBaz}) != Fail {
+ t.Error("whitelist misclassified baz")
+ }
}
func TestBlacklistClassifier(t *testing.T) {
@@ -63,4 +85,14 @@ func TestBlacklistClassifier(t *testing.T) {
if c.Classify(errBaz) != Retry {
t.Error("blacklist misclassified baz")
}
+
+ if c.Classify(wrappedErr{error: errFoo}) != Retry {
+ t.Error("blacklist misclassified foo")
+ }
+ if c.Classify(wrappedErr{error: errBar}) != Fail {
+ t.Error("blacklist misclassified bar")
+ }
+ if c.Classify(wrappedErr{error: errBaz}) != Retry {
+ t.Error("blacklist misclassified baz")
+ }
}
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/share/gocode/src/gopkg.in/eapache/go-resiliency.v1/go.mod
No differences were encountered in the control files