mirror of
https://github.com/status-im/status-go.git
synced 2025-02-02 09:56:52 +00:00
84cb5ca917
Now if Add is to be called it will be called before Wait, this is achieved by doing following: - if cancel() gets lock first and closes channelCh before spawnSync is called we will exit right away - if not than we will ensure that we hold a lock until syncers are spawned so that cancel() will be blocked for this time and it will prevent whole Terminate() from progressing
132 lines
4.4 KiB
Diff
132 lines
4.4 KiB
Diff
diff --git i/eth/downloader/downloader.go w/eth/downloader/downloader.go
|
|
index 43f0e3db9..b337f95c9 100644
|
|
--- i/eth/downloader/downloader.go
|
|
+++ w/eth/downloader/downloader.go
|
|
@@ -143,6 +143,8 @@ type Downloader struct {
|
|
quitCh chan struct{} // Quit channel to signal termination
|
|
quitLock sync.RWMutex // Lock to prevent double closes
|
|
|
|
+ downloads sync.WaitGroup // Keeps track of the currently active downloads
|
|
+
|
|
// Testing hooks
|
|
syncInitHook func(uint64, uint64) // Method to call upon initiating a new sync run
|
|
bodyFetchHook func([]*types.Header) // Method to call upon starting a block body fetch
|
|
@@ -403,7 +405,9 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode
|
|
// specified peer and head hash.
|
|
func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.Int) (err error) {
|
|
d.mux.Post(StartEvent{})
|
|
+ d.downloads.Add(1)
|
|
defer func() {
|
|
+ d.downloads.Done()
|
|
// reset on error
|
|
if err != nil {
|
|
d.mux.Post(FailedEvent{err})
|
|
@@ -471,14 +475,22 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
|
|
} else if d.mode == FullSync {
|
|
fetchers = append(fetchers, d.processFullSyncContent)
|
|
}
|
|
- return d.spawnSync(fetchers)
|
|
+ return d.spawnSync(errCancelHeaderFetch, fetchers)
|
|
}
|
|
|
|
// spawnSync runs d.process and all given fetcher functions to completion in
|
|
// separate goroutines, returning the first error that appears.
|
|
-func (d *Downloader) spawnSync(fetchers []func() error) error {
|
|
+func (d *Downloader) spawnSync(errCancel error, fetchers []func() error) error {
|
|
+ d.cancelLock.Lock()
|
|
+ select {
|
|
+ case <-d.cancelCh:
|
|
+ d.cancelLock.Unlock()
|
|
+ return errCancel
|
|
+ default:
|
|
+ }
|
|
errc := make(chan error, len(fetchers))
|
|
d.cancelWg.Add(len(fetchers))
|
|
+ d.cancelLock.Unlock()
|
|
for _, fn := range fetchers {
|
|
fn := fn
|
|
go func() { defer d.cancelWg.Done(); errc <- fn() }()
|
|
@@ -539,6 +551,10 @@ func (d *Downloader) Terminate() {
|
|
|
|
// Cancel any pending download requests
|
|
d.Cancel()
|
|
+
|
|
+ // Wait, so external dependencies aren't destroyed
|
|
+ // until the download processing is done.
|
|
+ d.downloads.Wait()
|
|
}
|
|
|
|
// fetchHeight retrieves the head header of the remote peer to aid in estimating
|
|
diff --git i/eth/handler.go w/eth/handler.go
|
|
index 4069359c9..da9ebb243 100644
|
|
--- i/eth/handler.go
|
|
+++ w/eth/handler.go
|
|
@@ -230,6 +230,9 @@ func (pm *ProtocolManager) Stop() {
|
|
// Quit fetcher, txsyncLoop.
|
|
close(pm.quitSync)
|
|
|
|
+ // Stop downloader and make sure that all the running downloads are complete.
|
|
+ pm.downloader.Terminate()
|
|
+
|
|
// Disconnect existing sessions.
|
|
// This also closes the gate for any new registrations on the peer set.
|
|
// sessions which are already established but not added to pm.peers yet
|
|
diff --git i/eth/sync.go w/eth/sync.go
|
|
index e49e40087..4367434a6 100644
|
|
--- i/eth/sync.go
|
|
+++ w/eth/sync.go
|
|
@@ -135,7 +135,6 @@ func (pm *ProtocolManager) syncer() {
|
|
// Start and ensure cleanup of sync mechanisms
|
|
pm.fetcher.Start()
|
|
defer pm.fetcher.Stop()
|
|
- defer pm.downloader.Terminate()
|
|
|
|
// Wait for different events to fire synchronisation operations
|
|
forceSync := time.NewTicker(forceSyncCycle)
|
|
diff --git i/les/backend.go w/les/backend.go
|
|
index 6a324cb04..e3844bf84 100644
|
|
--- i/les/backend.go
|
|
+++ w/les/backend.go
|
|
@@ -20,7 +20,6 @@ package les
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
- "time"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
@@ -250,7 +249,6 @@ func (s *LightEthereum) Stop() error {
|
|
|
|
s.eventMux.Stop()
|
|
|
|
- time.Sleep(time.Millisecond * 200)
|
|
s.chainDb.Close()
|
|
close(s.shutdownChan)
|
|
|
|
diff --git i/les/handler.go w/les/handler.go
|
|
index 9627f392b..f2bbe899f 100644
|
|
--- i/les/handler.go
|
|
+++ w/les/handler.go
|
|
@@ -241,6 +241,9 @@ func (pm *ProtocolManager) Stop() {
|
|
|
|
close(pm.quitSync) // quits syncer, fetcher
|
|
|
|
+ // Stop downloader and make sure that all the running downloads are complete.
|
|
+ pm.downloader.Terminate()
|
|
+
|
|
// Disconnect existing sessions.
|
|
// This also closes the gate for any new registrations on the peer set.
|
|
// sessions which are already established but not added to pm.peers yet
|
|
diff --git i/les/sync.go w/les/sync.go
|
|
index c3d37e2f3..fc1f076c7 100644
|
|
--- i/les/sync.go
|
|
+++ w/les/sync.go
|
|
@@ -31,7 +31,6 @@ func (pm *ProtocolManager) syncer() {
|
|
// Start and ensure cleanup of sync mechanisms
|
|
//pm.fetcher.Start()
|
|
//defer pm.fetcher.Stop()
|
|
- defer pm.downloader.Terminate()
|
|
|
|
// Wait for different events to fire synchronisation operations
|
|
//forceSync := time.Tick(forceSyncCycle)
|