les: wait for all task goroutines before dropping the peer (#20010)
* les: wait all task routines before drop the peer * les: address comments * les: fix issue
This commit is contained in:
committed by
Péter Szilágyi
parent
a978adfd7c
commit
68502595f6
@ -54,7 +54,10 @@ const (
|
||||
MaxTxStatus = 256 // Amount of transactions to queried per request
|
||||
)
|
||||
|
||||
var errTooManyInvalidRequest = errors.New("too many invalid requests made")
|
||||
var (
|
||||
errTooManyInvalidRequest = errors.New("too many invalid requests made")
|
||||
errFullClientPool = errors.New("client pool is full")
|
||||
)
|
||||
|
||||
// serverHandler is responsible for serving light client and process
|
||||
// all incoming light requests.
|
||||
@ -124,23 +127,26 @@ func (h *serverHandler) handle(p *peer) error {
|
||||
}
|
||||
defer p.fcClient.Disconnect()
|
||||
|
||||
// Disconnect the inbound peer if it's rejected by clientPool
|
||||
if !h.server.clientPool.connect(p, 0) {
|
||||
p.Log().Debug("Light Ethereum peer registration failed", "err", errFullClientPool)
|
||||
return errFullClientPool
|
||||
}
|
||||
// Register the peer locally
|
||||
if err := h.server.peers.Register(p); err != nil {
|
||||
h.server.clientPool.disconnect(p)
|
||||
p.Log().Error("Light Ethereum peer registration failed", "err", err)
|
||||
return err
|
||||
}
|
||||
clientConnectionGauge.Update(int64(h.server.peers.Len()))
|
||||
|
||||
// add dummy balance tracker for tests
|
||||
if p.balanceTracker == nil {
|
||||
p.balanceTracker = &balanceTracker{}
|
||||
p.balanceTracker.init(&mclock.System{}, 1)
|
||||
}
|
||||
var wg sync.WaitGroup // Wait group used to track all in-flight task routines.
|
||||
|
||||
connectedAt := mclock.Now()
|
||||
defer func() {
|
||||
p.balanceTracker = nil
|
||||
wg.Wait() // Ensure all background task routines have exited.
|
||||
h.server.peers.Unregister(p.id)
|
||||
h.server.clientPool.disconnect(p)
|
||||
clientConnectionGauge.Update(int64(h.server.peers.Len()))
|
||||
connectionTimer.Update(time.Duration(mclock.Now() - connectedAt))
|
||||
}()
|
||||
@ -153,7 +159,7 @@ func (h *serverHandler) handle(p *peer) error {
|
||||
return err
|
||||
default:
|
||||
}
|
||||
if err := h.handleMsg(p); err != nil {
|
||||
if err := h.handleMsg(p, &wg); err != nil {
|
||||
p.Log().Debug("Light Ethereum message handling failed", "err", err)
|
||||
return err
|
||||
}
|
||||
@ -162,7 +168,7 @@ func (h *serverHandler) handle(p *peer) error {
|
||||
|
||||
// handleMsg is invoked whenever an inbound message is received from a remote
|
||||
// peer. The remote connection is torn down upon returning any error.
|
||||
func (h *serverHandler) handleMsg(p *peer) error {
|
||||
func (h *serverHandler) handleMsg(p *peer, wg *sync.WaitGroup) error {
|
||||
// Read the next message from the remote peer, and ensure it's fully consumed
|
||||
msg, err := p.rw.ReadMsg()
|
||||
if err != nil {
|
||||
@ -243,7 +249,7 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
// Feed cost tracker request serving statistic.
|
||||
h.server.costTracker.updateStats(msg.Code, amount, servingTime, realCost)
|
||||
// Reduce priority "balance" for the specific peer.
|
||||
p.balanceTracker.requestCost(realCost)
|
||||
h.server.clientPool.requestCost(p, realCost)
|
||||
}
|
||||
if reply != nil {
|
||||
p.queueSend(func() {
|
||||
@ -273,7 +279,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
}
|
||||
query := req.Query
|
||||
if accept(req.ReqID, query.Amount, MaxHeaderFetch) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
hashMode := query.Origin.Hash != (common.Hash{})
|
||||
first := true
|
||||
maxNonCanonical := uint64(100)
|
||||
@ -387,7 +395,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
)
|
||||
reqCnt := len(req.Hashes)
|
||||
if accept(req.ReqID, uint64(reqCnt), MaxBodyFetch) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i, hash := range req.Hashes {
|
||||
if i != 0 && !task.waitOrStop() {
|
||||
sendResponse(req.ReqID, 0, nil, task.servingTime)
|
||||
@ -433,7 +443,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
)
|
||||
reqCnt := len(req.Reqs)
|
||||
if accept(req.ReqID, uint64(reqCnt), MaxCodeFetch) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i, request := range req.Reqs {
|
||||
if i != 0 && !task.waitOrStop() {
|
||||
sendResponse(req.ReqID, 0, nil, task.servingTime)
|
||||
@ -502,7 +514,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
)
|
||||
reqCnt := len(req.Hashes)
|
||||
if accept(req.ReqID, uint64(reqCnt), MaxReceiptFetch) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i, hash := range req.Hashes {
|
||||
if i != 0 && !task.waitOrStop() {
|
||||
sendResponse(req.ReqID, 0, nil, task.servingTime)
|
||||
@ -557,7 +571,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
)
|
||||
reqCnt := len(req.Reqs)
|
||||
if accept(req.ReqID, uint64(reqCnt), MaxProofsFetch) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
nodes := light.NewNodeSet()
|
||||
|
||||
for i, request := range req.Reqs {
|
||||
@ -658,7 +674,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
)
|
||||
reqCnt := len(req.Reqs)
|
||||
if accept(req.ReqID, uint64(reqCnt), MaxHelperTrieProofsFetch) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
var (
|
||||
lastIdx uint64
|
||||
lastType uint
|
||||
@ -725,7 +743,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
}
|
||||
reqCnt := len(req.Txs)
|
||||
if accept(req.ReqID, uint64(reqCnt), MaxTxSend) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
stats := make([]light.TxStatus, len(req.Txs))
|
||||
for i, tx := range req.Txs {
|
||||
if i != 0 && !task.waitOrStop() {
|
||||
@ -771,7 +791,9 @@ func (h *serverHandler) handleMsg(p *peer) error {
|
||||
}
|
||||
reqCnt := len(req.Hashes)
|
||||
if accept(req.ReqID, uint64(reqCnt), MaxTxStatus) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
stats := make([]light.TxStatus, len(req.Hashes))
|
||||
for i, hash := range req.Hashes {
|
||||
if i != 0 && !task.waitOrStop() {
|
||||
|
Reference in New Issue
Block a user