Merge pull request #14067 from ahrtr/lease_revoke

Fix the race condition between goroutine and channel on the same leases to be revoked
This commit is contained in:
Benjamin Wang 2022-05-29 05:04:26 +08:00 committed by GitHub
commit ce77d83ee6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -842,19 +842,37 @@ func (s *EtcdServer) run() {
f := func(context.Context) { s.applyAll(&ep, &ap) } f := func(context.Context) { s.applyAll(&ep, &ap) }
sched.Schedule(f) sched.Schedule(f)
case leases := <-expiredLeaseC: case leases := <-expiredLeaseC:
s.revokeExpiredLeases(leases)
case err := <-s.errorc:
lg.Warn("server error", zap.Error(err))
lg.Warn("data-dir used by this member must be removed")
return
case <-getSyncC():
if s.v2store.HasTTLKeys() {
s.sync(s.Cfg.ReqTimeout())
}
case <-s.stop:
return
}
}
}
func (s *EtcdServer) revokeExpiredLeases(leases []*lease.Lease) {
s.GoAttach(func() { s.GoAttach(func() {
lg := s.Logger()
// Increases throughput of expired leases deletion process through parallelization // Increases throughput of expired leases deletion process through parallelization
c := make(chan struct{}, maxPendingRevokes) c := make(chan struct{}, maxPendingRevokes)
for _, lease := range leases { for _, curLease := range leases {
select { select {
case c <- struct{}{}: case c <- struct{}{}:
case <-s.stopping: case <-s.stopping:
return return
} }
lid := lease.ID
f := func(lid int64) {
s.GoAttach(func() { s.GoAttach(func() {
ctx := s.authStore.WithRoot(s.ctx) ctx := s.authStore.WithRoot(s.ctx)
_, lerr := s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: int64(lid)}) _, lerr := s.LeaseRevoke(ctx, &pb.LeaseRevokeRequest{ID: lid})
if lerr == nil { if lerr == nil {
leaseExpired.Inc() leaseExpired.Inc()
} else { } else {
@ -868,19 +886,10 @@ func (s *EtcdServer) run() {
<-c <-c
}) })
} }
f(int64(curLease.ID))
}
}) })
case err := <-s.errorc:
lg.Warn("server error", zap.Error(err))
lg.Warn("data-dir used by this member must be removed")
return
case <-getSyncC():
if s.v2store.HasTTLKeys() {
s.sync(s.Cfg.ReqTimeout())
}
case <-s.stop:
return
}
}
} }
// Cleanup removes allocated objects by EtcdServer.NewServer in // Cleanup removes allocated objects by EtcdServer.NewServer in