Skip to content

Commit f0dfb9e

Browse files
committed
Add retry and backoff - taken from bradfitz#54
1 parent fb4bf63 commit f0dfb9e

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

memcache/memcache.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"errors"
2424
"fmt"
2525
"io"
26+
"math"
2627
"net"
2728

2829
"strconv"
@@ -70,6 +71,8 @@ const (
7071
// DefaultMaxIdleConns is the default maximum number of idle connections
7172
// kept for any single address.
7273
DefaultMaxIdleConns = 2
74+
maxIdleConnsPerAddr = 2
75+
maxRetries = 10 // maximum number of times to attempt to reconnect
7376
)
7477

7578
const buffered = 8 // arbitrary buffered channel size, for readability
@@ -347,7 +350,26 @@ func (c *Client) withAddrRw(addr net.Addr, fn func(*bufio.ReadWriter) error) (er
347350
return err
348351
}
349352
defer cn.condRelease(&err)
350-
return fn(cn.rw)
353+
// Exponential backoff (based on Ethernet)
354+
retries := 0
355+
err = fn(cn.rw)
356+
if err == io.EOF { // Bad connection
357+
cn.nc.Close()
358+
359+
for err != nil && retries < maxRetries {
360+
retries++
361+
backoffCoefficient := int(math.Pow(float64(2), float64(retries))) - 1
362+
sleepFor := time.Nanosecond * time.Duration(50000*backoffCoefficient)
363+
time.Sleep(sleepFor)
364+
cn, err = c.getConn(addr)
365+
if err != nil {
366+
continue
367+
}
368+
err = fn(cn.rw)
369+
}
370+
}
371+
372+
return
351373
}
352374

353375
func (c *Client) withKeyRw(key string, fn func(*bufio.ReadWriter) error) error {

0 commit comments

Comments
 (0)