mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
fix: use time.After in loop, possible memory leaks
This commit is contained in:
parent
758fce71fa
commit
89f5aa6104
7 changed files with 53 additions and 14 deletions
|
|
@ -596,6 +596,9 @@ func (s *MatcherSession) deliverSections(bit uint, sections []uint64, bitsets []
|
||||||
// of the session, any request in-flight need to be responded to! Empty responses
|
// of the session, any request in-flight need to be responded to! Empty responses
|
||||||
// are fine though in that case.
|
// are fine though in that case.
|
||||||
func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan *Retrieval) {
|
func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan *Retrieval) {
|
||||||
|
waitTimer := time.NewTimer(wait)
|
||||||
|
defer waitTimer.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Allocate a new bloom bit index to retrieve data for, stopping when done
|
// Allocate a new bloom bit index to retrieve data for, stopping when done
|
||||||
bit, ok := s.allocateRetrieval()
|
bit, ok := s.allocateRetrieval()
|
||||||
|
|
@ -604,6 +607,7 @@ func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan
|
||||||
}
|
}
|
||||||
// Bit allocated, throttle a bit if we're below our batch limit
|
// Bit allocated, throttle a bit if we're below our batch limit
|
||||||
if s.pendingSections(bit) < batch {
|
if s.pendingSections(bit) < batch {
|
||||||
|
waitTimer.Reset(wait)
|
||||||
select {
|
select {
|
||||||
case <-s.quit:
|
case <-s.quit:
|
||||||
// Session terminating, we can't meaningfully service, abort
|
// Session terminating, we can't meaningfully service, abort
|
||||||
|
|
@ -611,7 +615,7 @@ func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan
|
||||||
s.deliverSections(bit, []uint64{}, [][]byte{})
|
s.deliverSections(bit, []uint64{}, [][]byte{})
|
||||||
return
|
return
|
||||||
|
|
||||||
case <-time.After(wait):
|
case <-waitTimer.C:
|
||||||
// Throttling up, fetch whatever is available
|
// Throttling up, fetch whatever is available
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,10 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||||
localHeaders = d.readHeaderRange(tail, int(count))
|
localHeaders = d.readHeaderRange(tail, int(count))
|
||||||
log.Warn("Retrieved beacon headers from local", "from", from, "count", count)
|
log.Warn("Retrieved beacon headers from local", "from", from, "count", count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fsHeaderContCheckTimer := time.NewTimer(fsHeaderContCheck)
|
||||||
|
defer fsHeaderContCheckTimer.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Some beacon headers might have appeared since the last cycle, make
|
// Some beacon headers might have appeared since the last cycle, make
|
||||||
// sure we're always syncing to all available ones
|
// sure we're always syncing to all available ones
|
||||||
|
|
@ -381,8 +385,9 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||||
}
|
}
|
||||||
// State sync still going, wait a bit for new headers and retry
|
// State sync still going, wait a bit for new headers and retry
|
||||||
log.Trace("Pivot not yet committed, waiting...")
|
log.Trace("Pivot not yet committed, waiting...")
|
||||||
|
fsHeaderContCheckTimer.Reset(fsHeaderContCheck)
|
||||||
select {
|
select {
|
||||||
case <-time.After(fsHeaderContCheck):
|
case <-fsHeaderContCheckTimer.C:
|
||||||
case <-d.cancelCh:
|
case <-d.cancelCh:
|
||||||
return errCanceled
|
return errCanceled
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1020,6 +1020,10 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, head uint64) e
|
||||||
ancestor = from
|
ancestor = from
|
||||||
mode = d.getMode()
|
mode = d.getMode()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fsHeaderContCheckTimer := time.NewTimer(fsHeaderContCheck)
|
||||||
|
defer fsHeaderContCheckTimer.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Pull the next batch of headers, it either:
|
// Pull the next batch of headers, it either:
|
||||||
// - Pivot check to see if the chain moved too far
|
// - Pivot check to see if the chain moved too far
|
||||||
|
|
@ -1124,8 +1128,9 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, head uint64) e
|
||||||
// Don't abort header fetches while the pivot is downloading
|
// Don't abort header fetches while the pivot is downloading
|
||||||
if !d.committed.Load() && pivot <= from {
|
if !d.committed.Load() && pivot <= from {
|
||||||
p.log.Debug("No headers, waiting for pivot commit")
|
p.log.Debug("No headers, waiting for pivot commit")
|
||||||
|
fsHeaderContCheckTimer.Reset(fsHeaderContCheck)
|
||||||
select {
|
select {
|
||||||
case <-time.After(fsHeaderContCheck):
|
case <-fsHeaderContCheckTimer.C:
|
||||||
continue
|
continue
|
||||||
case <-d.cancelCh:
|
case <-d.cancelCh:
|
||||||
return errCanceled
|
return errCanceled
|
||||||
|
|
@ -1194,9 +1199,10 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, head uint64) e
|
||||||
// sleep a bit and retry. Take care with headers already consumed during
|
// sleep a bit and retry. Take care with headers already consumed during
|
||||||
// skeleton filling
|
// skeleton filling
|
||||||
if len(headers) == 0 && !progressed {
|
if len(headers) == 0 && !progressed {
|
||||||
|
fsHeaderContCheckTimer.Reset(fsHeaderContCheck)
|
||||||
p.log.Trace("All headers delayed, waiting")
|
p.log.Trace("All headers delayed, waiting")
|
||||||
select {
|
select {
|
||||||
case <-time.After(fsHeaderContCheck):
|
case <-fsHeaderContCheckTimer.C:
|
||||||
continue
|
continue
|
||||||
case <-d.cancelCh:
|
case <-d.cancelCh:
|
||||||
return errCanceled
|
return errCanceled
|
||||||
|
|
@ -1274,9 +1280,13 @@ func (d *Downloader) fetchReceipts(from uint64, beaconMode bool) error {
|
||||||
// queue until the stream ends or a failure occurs.
|
// queue until the stream ends or a failure occurs.
|
||||||
func (d *Downloader) processHeaders(origin uint64, td, ttd *big.Int, beaconMode bool) error {
|
func (d *Downloader) processHeaders(origin uint64, td, ttd *big.Int, beaconMode bool) error {
|
||||||
var (
|
var (
|
||||||
mode = d.getMode()
|
mode = d.getMode()
|
||||||
gotHeaders = false // Wait for batches of headers to process
|
gotHeaders = false // Wait for batches of headers to process
|
||||||
|
secondTimer = time.NewTimer(time.Second)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
defer secondTimer.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-d.cancelCh:
|
case <-d.cancelCh:
|
||||||
|
|
@ -1397,10 +1407,11 @@ func (d *Downloader) processHeaders(origin uint64, td, ttd *big.Int, beaconMode
|
||||||
if mode == FullSync || mode == SnapSync {
|
if mode == FullSync || mode == SnapSync {
|
||||||
// If we've reached the allowed number of pending headers, stall a bit
|
// If we've reached the allowed number of pending headers, stall a bit
|
||||||
for d.queue.PendingBodies() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders {
|
for d.queue.PendingBodies() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders {
|
||||||
|
secondTimer.Reset(time.Second)
|
||||||
select {
|
select {
|
||||||
case <-d.cancelCh:
|
case <-d.cancelCh:
|
||||||
return errCanceled
|
return errCanceled
|
||||||
case <-time.After(time.Second):
|
case <-secondTimer.C:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Otherwise insert the headers for content retrieval
|
// Otherwise insert the headers for content retrieval
|
||||||
|
|
@ -1565,9 +1576,11 @@ func (d *Downloader) processSnapSyncContent() error {
|
||||||
// Note, there's no issue with memory piling up since after 64 blocks the
|
// Note, there's no issue with memory piling up since after 64 blocks the
|
||||||
// pivot will forcefully move so these accumulators will be dropped.
|
// pivot will forcefully move so these accumulators will be dropped.
|
||||||
var (
|
var (
|
||||||
oldPivot *fetchResult // Locked in pivot block, might change eventually
|
oldPivot *fetchResult // Locked in pivot block, might change eventually
|
||||||
oldTail []*fetchResult // Downloaded content after the pivot
|
oldTail []*fetchResult // Downloaded content after the pivot
|
||||||
|
secondTimer = time.NewTimer(time.Second)
|
||||||
)
|
)
|
||||||
|
defer secondTimer.Stop()
|
||||||
for {
|
for {
|
||||||
// Wait for the next batch of downloaded data to be available. If we have
|
// Wait for the next batch of downloaded data to be available. If we have
|
||||||
// not yet reached the pivot point, wait blockingly as there's no need to
|
// not yet reached the pivot point, wait blockingly as there's no need to
|
||||||
|
|
@ -1650,6 +1663,7 @@ func (d *Downloader) processSnapSyncContent() error {
|
||||||
oldPivot = P
|
oldPivot = P
|
||||||
}
|
}
|
||||||
// Wait for completion, occasionally checking for pivot staleness
|
// Wait for completion, occasionally checking for pivot staleness
|
||||||
|
secondTimer.Reset(time.Second)
|
||||||
select {
|
select {
|
||||||
case <-sync.done:
|
case <-sync.done:
|
||||||
if sync.err != nil {
|
if sync.err != nil {
|
||||||
|
|
@ -1660,7 +1674,7 @@ func (d *Downloader) processSnapSyncContent() error {
|
||||||
}
|
}
|
||||||
oldPivot = nil
|
oldPivot = nil
|
||||||
|
|
||||||
case <-time.After(time.Second):
|
case <-secondTimer.C:
|
||||||
oldTail = afterP
|
oldTail = afterP
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -544,10 +544,14 @@ func (s *Service) reportLatency(conn *connWrapper) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Wait for the pong request to arrive back
|
// Wait for the pong request to arrive back
|
||||||
|
|
||||||
|
timer := time.NewTimer(5 * time.Second)
|
||||||
|
defer timer.Stop()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-s.pongCh:
|
case <-s.pongCh:
|
||||||
// Pong delivered, report the latency
|
// Pong delivered, report the latency
|
||||||
case <-time.After(5 * time.Second):
|
case <-timer.C:
|
||||||
// Ping timeout, abort
|
// Ping timeout, abort
|
||||||
return errors.New("ping timed out")
|
return errors.New("ping timed out")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -303,10 +303,14 @@ func (n *ExecNode) Stop() error {
|
||||||
go func() {
|
go func() {
|
||||||
waitErr <- n.Cmd.Wait()
|
waitErr <- n.Cmd.Wait()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
timer := time.NewTimer(5 * time.Second)
|
||||||
|
defer timer.Stop()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case err := <-waitErr:
|
case err := <-waitErr:
|
||||||
return err
|
return err
|
||||||
case <-time.After(5 * time.Second):
|
case <-timer.C:
|
||||||
return n.Cmd.Process.Kill()
|
return n.Cmd.Process.Kill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,10 @@ func startStop(net *Network, quit chan struct{}, nodeCount int) {
|
||||||
}
|
}
|
||||||
tick := time.NewTicker(10 * time.Second)
|
tick := time.NewTicker(10 * time.Second)
|
||||||
defer tick.Stop()
|
defer tick.Stop()
|
||||||
|
|
||||||
|
timer := time.NewTimer(3 * time.Second)
|
||||||
|
defer timer.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-quit:
|
case <-quit:
|
||||||
|
|
@ -80,11 +84,12 @@ func startStop(net *Network, quit chan struct{}, nodeCount int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer.Reset(3 * time.Second)
|
||||||
select {
|
select {
|
||||||
case <-quit:
|
case <-quit:
|
||||||
log.Info("Terminating simulation loop")
|
log.Info("Terminating simulation loop")
|
||||||
return
|
return
|
||||||
case <-time.After(3 * time.Second):
|
case <-timer.C:
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("starting node", "id", id)
|
log.Debug("starting node", "id", id)
|
||||||
|
|
|
||||||
|
|
@ -1028,11 +1028,14 @@ func (net *Network) Load(snap *Snapshot) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snapshotLoadTimeoutTimer := time.NewTimer(snapshotLoadTimeout)
|
||||||
|
defer snapshotLoadTimeoutTimer.Stop()
|
||||||
|
|
||||||
select {
|
select {
|
||||||
// Wait until all connections from the snapshot are established.
|
// Wait until all connections from the snapshot are established.
|
||||||
case <-allConnected:
|
case <-allConnected:
|
||||||
// Make sure that we do not wait forever.
|
// Make sure that we do not wait forever.
|
||||||
case <-time.After(snapshotLoadTimeout):
|
case <-snapshotLoadTimeoutTimer.C:
|
||||||
return errors.New("snapshot connections not established")
|
return errors.New("snapshot connections not established")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue