|
@@ -6,9 +6,12 @@ package gocql
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"fmt"
|
|
"fmt"
|
|
|
|
|
+ "math"
|
|
|
|
|
+ "math/rand"
|
|
|
"net"
|
|
"net"
|
|
|
"sync"
|
|
"sync"
|
|
|
"sync/atomic"
|
|
"sync/atomic"
|
|
|
|
|
+ "time"
|
|
|
|
|
|
|
|
"github.com/hailocab/go-hostpool"
|
|
"github.com/hailocab/go-hostpool"
|
|
|
)
|
|
)
|
|
@@ -159,6 +162,34 @@ func (s *SimpleRetryPolicy) Attempt(q RetryableQuery) bool {
|
|
|
return q.Attempts() <= s.NumRetries
|
|
return q.Attempts() <= s.NumRetries
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+// ExponentialBackoffRetryPolicy sleeps between attempts
|
|
|
|
|
+type ExponentialBackoffRetryPolicy struct {
|
|
|
|
|
+ NumRetries int
|
|
|
|
|
+ Min, Max time.Duration
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (e *ExponentialBackoffRetryPolicy) Attempt(q RetryableQuery) bool {
|
|
|
|
|
+ if q.Attempts() > e.NumRetries {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+ time.Sleep(e.napTime(q.Attempts()))
|
|
|
|
|
+ return true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (e *ExponentialBackoffRetryPolicy) napTime(attempts int) time.Duration {
|
|
|
|
|
+ if e.Min <= 0 {
|
|
|
|
|
+ e.Min = 100 * time.Millisecond
|
|
|
|
|
+ }
|
|
|
|
|
+ if e.Max <= 0 {
|
|
|
|
|
+ e.Max = 10 * time.Second
|
|
|
|
|
+ }
|
|
|
|
|
+ minFloat := float64(e.Min)
|
|
|
|
|
+ napDuration := minFloat * math.Pow(2, float64(attempts-1))
|
|
|
|
|
+ // add some jitter
|
|
|
|
|
+ napDuration += rand.Float64()*minFloat - (minFloat / 2)
|
|
|
|
|
+ return time.Duration(napDuration)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
type HostStateNotifier interface {
|
|
type HostStateNotifier interface {
|
|
|
AddHost(host *HostInfo)
|
|
AddHost(host *HostInfo)
|
|
|
RemoveHost(host *HostInfo)
|
|
RemoveHost(host *HostInfo)
|