etcdserver: specify timeout caused by leader election
Before this PR, the timeout caused by leader election returns: ``` 14:45:37 etcd2 | 2015-08-12 14:45:37.786349 E | etcdhttp: got unexpected response error (etcdserver: request timed out) ``` After this PR: ``` 15:52:54 etcd1 | 2015-08-12 15:52:54.389523 E | etcdhttp: etcdserver: request timed out, possibly due to leader down ``` Conflicts: etcdserver/raft.go
This commit is contained in:
@ -551,7 +551,7 @@ func (s *EtcdServer) Do(ctx context.Context, r pb.Request) (Response, error) {
|
||||
case <-ctx.Done():
|
||||
proposeFailed.Inc()
|
||||
s.w.Trigger(r.ID, nil) // GC wait
|
||||
return Response{}, parseCtxErr(ctx.Err())
|
||||
return Response{}, s.parseProposeCtxErr(ctx.Err(), start)
|
||||
case <-s.done:
|
||||
return Response{}, ErrStopped
|
||||
}
|
||||
@ -646,6 +646,7 @@ func (s *EtcdServer) Leader() types.ID { return types.ID(s.Lead()) }
|
||||
func (s *EtcdServer) configure(ctx context.Context, cc raftpb.ConfChange) error {
|
||||
cc.ID = s.reqIDGen.Next()
|
||||
ch := s.w.Register(cc.ID)
|
||||
start := time.Now()
|
||||
if err := s.r.ProposeConfChange(ctx, cc); err != nil {
|
||||
s.w.Trigger(cc.ID, nil)
|
||||
return err
|
||||
@ -661,7 +662,7 @@ func (s *EtcdServer) configure(ctx context.Context, cc raftpb.ConfChange) error
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
s.w.Trigger(cc.ID, nil) // GC wait
|
||||
return parseCtxErr(ctx.Err())
|
||||
return s.parseProposeCtxErr(ctx.Err(), start)
|
||||
case <-s.done:
|
||||
return ErrStopped
|
||||
}
|
||||
@ -1002,3 +1003,19 @@ func (s *EtcdServer) updateClusterVersion(ver string) {
|
||||
plog.Errorf("error updating cluster version (%v)", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *EtcdServer) parseProposeCtxErr(err error, start time.Time) error {
|
||||
switch err {
|
||||
case context.Canceled:
|
||||
return ErrCanceled
|
||||
case context.DeadlineExceeded:
|
||||
curLeadElected := s.r.leadElectedTime()
|
||||
prevLeadLost := curLeadElected.Add(-2 * time.Duration(s.cfg.ElectionTicks) * time.Duration(s.cfg.TickMs) * time.Millisecond)
|
||||
if start.After(prevLeadLost) && start.Before(curLeadElected) {
|
||||
return ErrTimeoutDueToLeaderLost
|
||||
}
|
||||
return ErrTimeout
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user