Skip to content

Commit

Permalink
etcdserver: translate EOF to ErrNoLeader for renew, timetolive
Browse files Browse the repository at this point in the history
Address etcd-io#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.
  • Loading branch information
gyuho committed Nov 3, 2016
1 parent 3782571 commit cc304ac
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions etcdserver/v3_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package etcdserver
import (
"bytes"
"encoding/binary"
"io"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -326,6 +327,7 @@ func (s *EtcdServer) LeaseRenew(id lease.LeaseID) (int64, error) {
if err == nil {
break
}
err = convertEOFToNoLeader(err)
}
return ttl, err
}
Expand Down Expand Up @@ -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++ {
Expand Down

0 comments on commit cc304ac

Please sign in to comment.