-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add backoff package and fix Consul CPU usage #635
Changes from 7 commits
924501a
12eacfb
0ad6586
99319fb
8c60620
10620f3
9e8371f
dc88158
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,14 @@ package consul | |
import ( | ||
"fmt" | ||
"io" | ||
"time" | ||
|
||
consul "github.com/hashicorp/consul/api" | ||
|
||
"github.com/go-kit/kit/log" | ||
"github.com/go-kit/kit/sd" | ||
"github.com/go-kit/kit/sd/internal/instance" | ||
"github.com/go-kit/kit/util/conn" | ||
) | ||
|
||
const defaultIndex = 0 | ||
|
@@ -59,6 +61,7 @@ func (s *Instancer) loop(lastIndex uint64) { | |
var ( | ||
instances []string | ||
err error | ||
d time.Duration = time.Millisecond * 10 | ||
) | ||
for { | ||
instances, lastIndex, err = s.getInstances(lastIndex, s.quitc) | ||
|
@@ -70,6 +73,8 @@ func (s *Instancer) loop(lastIndex uint64) { | |
s.cache.Update(sd.Event{Err: err}) | ||
default: | ||
s.cache.Update(sd.Event{Instances: instances}) | ||
time.Sleep(d) | ||
d = conn.Exponential(d) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for not catching this earlier. We want to implement an upper limit e.g. 30s, and have a successful reconnect reset the |
||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ package conn | |
|
||
import ( | ||
"errors" | ||
"math/rand" | ||
"net" | ||
"time" | ||
|
||
|
@@ -103,7 +104,7 @@ func (m *Manager) loop() { | |
case conn = <-connc: | ||
if conn == nil { | ||
// didn't work | ||
backoff = exponential(backoff) // wait longer | ||
backoff = Exponential(backoff) // wait longer | ||
reconnectc = m.after(backoff) // try again | ||
} else { | ||
// worked! | ||
|
@@ -132,12 +133,18 @@ func dial(d Dialer, network, address string, logger log.Logger) net.Conn { | |
return conn | ||
} | ||
|
||
func exponential(d time.Duration) time.Duration { | ||
// Exponential takes a duration and returns another one that is twice as long, +/- 50%. It is | ||
// used to provide backoff for operations that may fail and should avoid thundering herds. | ||
// See https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ for rationale | ||
func Exponential(d time.Duration) time.Duration { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we get some doc string here? :) |
||
d *= 2 | ||
jitter := rand.Float64() + 0.5 | ||
d = time.Duration(int64(float64(d.Nanoseconds()) * jitter)) | ||
if d > time.Minute { | ||
d = time.Minute | ||
} | ||
return d | ||
|
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm thinking a 1-line change can be enough, something like this, feel free to make corrections... func exponential(d time.Duration) time.Duration {
d *= 2
if d > time.Minute {
d = time.Minute
}
return d * (rand.Float64() + 0.5)
} |
||
|
||
// ErrConnectionUnavailable is returned by the Manager's Write method when the | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
d = 10 * time.Millisecond
is preferable here.