etcdserver: translate EOF to ErrNoLeader for renew, timetolive

Address https://github.com/coreos/etcd/issues/6754.

In case there are network errors or unexpected EOF errors
in TimeToLive http requests to leader, we translate that into
ErrNoLeader, and expects the client to retry its request.
This commit is contained in:
Gyu-Ho Lee 2016-11-02 21:36:27 -07:00
parent 378257161f
commit cc304ac03c

View File

@ -17,6 +17,7 @@ package etcdserver
import (
"bytes"
"encoding/binary"
"io"
"strconv"
"strings"
"time"
@ -326,6 +327,7 @@ func (s *EtcdServer) LeaseRenew(id lease.LeaseID) (int64, error) {
if err == nil {
break
}
err = convertEOFToNoLeader(err)
}
return ttl, err
}
@ -363,10 +365,23 @@ func (s *EtcdServer) LeaseTimeToLive(ctx context.Context, r *pb.LeaseTimeToLiveR
if err == nil {
return iresp.LeaseTimeToLiveResponse, nil
}
err = convertEOFToNoLeader(err)
}
return nil, err
}
// convertEOFToNoLeader converts EOF erros to ErrNoLeader because
// lease renew, timetolive requests to followers are forwarded to leader,
// and follower might not be able to reach leader from transient network
// errors (often EOF errors). By returning ErrNoLeader, signal clients
// to retry its requests.
func convertEOFToNoLeader(err error) error {
if err == io.EOF || err == io.ErrUnexpectedEOF {
return ErrNoLeader
}
return err
}
func (s *EtcdServer) waitLeader() (*membership.Member, error) {
leader := s.cluster.Member(s.Leader())
for i := 0; i < 5 && leader == nil; i++ {