mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
Handle graceful shutdown in bor (#359)
* handle graceful shutdown in bor rest client * fix: log Co-authored-by: Jaynti Kanani <jdkanani@gmail.com> * add: handle shutdown using close channel * fix: create err variable for shutdown * use ticker instead of time.After for handling retry Co-authored-by: Jaynti Kanani <jdkanani@gmail.com>
This commit is contained in:
parent
d687d0d2de
commit
8e3d66c5e4
4 changed files with 38 additions and 9 deletions
|
|
@ -116,6 +116,9 @@ var (
|
||||||
// errOutOfRangeChain is returned if an authorization list is attempted to
|
// errOutOfRangeChain is returned if an authorization list is attempted to
|
||||||
// be modified via out-of-range or non-contiguous headers.
|
// be modified via out-of-range or non-contiguous headers.
|
||||||
errOutOfRangeChain = errors.New("out of range or non-contiguous chain")
|
errOutOfRangeChain = errors.New("out of range or non-contiguous chain")
|
||||||
|
|
||||||
|
// errShutdownDetected is returned if a shutdown was detected
|
||||||
|
errShutdownDetected = errors.New("shutdown detected")
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignerFn is a signer callback function to request a header to be signed by a
|
// SignerFn is a signer callback function to request a header to be signed by a
|
||||||
|
|
@ -916,6 +919,7 @@ func (c *Bor) APIs(chain consensus.ChainHeaderReader) []rpc.API {
|
||||||
|
|
||||||
// Close implements consensus.Engine. It's a noop for bor as there are no background threads.
|
// Close implements consensus.Engine. It's a noop for bor as there are no background threads.
|
||||||
func (c *Bor) Close() error {
|
func (c *Bor) Close() error {
|
||||||
|
c.HeimdallClient.Close()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,13 @@ type IHeimdallClient interface {
|
||||||
Fetch(path string, query string) (*ResponseWithHeight, error)
|
Fetch(path string, query string) (*ResponseWithHeight, error)
|
||||||
FetchWithRetry(path string, query string) (*ResponseWithHeight, error)
|
FetchWithRetry(path string, query string) (*ResponseWithHeight, error)
|
||||||
FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error)
|
FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error)
|
||||||
|
Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeimdallClient struct {
|
type HeimdallClient struct {
|
||||||
urlString string
|
urlString string
|
||||||
client http.Client
|
client http.Client
|
||||||
|
closeCh chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHeimdallClient(urlString string) (*HeimdallClient, error) {
|
func NewHeimdallClient(urlString string) (*HeimdallClient, error) {
|
||||||
|
|
@ -40,6 +42,7 @@ func NewHeimdallClient(urlString string) (*HeimdallClient, error) {
|
||||||
client: http.Client{
|
client: http.Client{
|
||||||
Timeout: time.Duration(5 * time.Second),
|
Timeout: time.Duration(5 * time.Second),
|
||||||
},
|
},
|
||||||
|
closeCh: make(chan struct{}),
|
||||||
}
|
}
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
@ -96,13 +99,22 @@ func (h *HeimdallClient) FetchWithRetry(rawPath string, rawQuery string) (*Respo
|
||||||
u.Path = rawPath
|
u.Path = rawPath
|
||||||
u.RawQuery = rawQuery
|
u.RawQuery = rawQuery
|
||||||
|
|
||||||
|
// create a new ticker for retrying the request
|
||||||
|
ticker := time.NewTicker(5 * time.Second)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
res, err := h.internalFetch(u)
|
select {
|
||||||
if err == nil && res != nil {
|
case <-h.closeCh:
|
||||||
return res, nil
|
log.Debug("Shutdown detected, terminating request")
|
||||||
|
return nil, errShutdownDetected
|
||||||
|
case <-ticker.C:
|
||||||
|
res, err := h.internalFetch(u)
|
||||||
|
if err == nil && res != nil {
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
log.Info("Retrying again in 5 seconds for next Heimdall data", "path", u.Path)
|
||||||
}
|
}
|
||||||
log.Info("Retrying again in 5 seconds for next Heimdall span", "path", u.Path)
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,3 +149,9 @@ func (h *HeimdallClient) internalFetch(u *url.URL) (*ResponseWithHeight, error)
|
||||||
|
|
||||||
return &response, nil
|
return &response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close sends a signal to stop the running process
|
||||||
|
func (h *HeimdallClient) Close() {
|
||||||
|
close(h.closeCh)
|
||||||
|
h.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -581,10 +581,12 @@ func (s *Ethereum) Stop() error {
|
||||||
// Then stop everything else.
|
// Then stop everything else.
|
||||||
s.bloomIndexer.Close()
|
s.bloomIndexer.Close()
|
||||||
close(s.closeBloomHandler)
|
close(s.closeBloomHandler)
|
||||||
s.txPool.Stop()
|
|
||||||
s.miner.Close()
|
// closing consensus engine first, as miner has deps on it
|
||||||
s.blockchain.Stop()
|
|
||||||
s.engine.Close()
|
s.engine.Close()
|
||||||
|
s.txPool.Stop()
|
||||||
|
s.blockchain.Stop()
|
||||||
|
s.miner.Close()
|
||||||
rawdb.PopUncleanShutdownMarker(s.chainDb)
|
rawdb.PopUncleanShutdownMarker(s.chainDb)
|
||||||
s.chainDb.Close()
|
s.chainDb.Close()
|
||||||
s.eventMux.Stop()
|
s.eventMux.Stop()
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
// Code generated by mockery v2.10.0. DO NOT EDIT.
|
||||||
|
|
||||||
package mocks
|
package mocks
|
||||||
|
|
||||||
|
|
@ -12,6 +12,11 @@ type IHeimdallClient struct {
|
||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close provides a mock function with given fields:
|
||||||
|
func (_m *IHeimdallClient) Close() {
|
||||||
|
_m.Called()
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch provides a mock function with given fields: path, query
|
// Fetch provides a mock function with given fields: path, query
|
||||||
func (_m *IHeimdallClient) Fetch(path string, query string) (*bor.ResponseWithHeight, error) {
|
func (_m *IHeimdallClient) Fetch(path string, query string) (*bor.ResponseWithHeight, error) {
|
||||||
ret := _m.Called(path, query)
|
ret := _m.Called(path, query)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue