2018-02-08 08:51:53 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"log"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/status-im/status-go/geth/common"
|
|
|
|
)
|
|
|
|
|
|
|
|
func createContextFromTimeout(timeout int) (context.Context, context.CancelFunc) {
|
|
|
|
if timeout == 0 {
|
|
|
|
return context.WithCancel(context.Background())
|
|
|
|
}
|
|
|
|
|
|
|
|
return context.WithTimeout(context.Background(), time.Duration(timeout)*time.Minute)
|
|
|
|
}
|
|
|
|
|
|
|
|
// syncAndStopNode tries to sync the blockchain and stop the node.
|
|
|
|
// It returns an exit code (`0` if successful or `1` in case of error)
|
|
|
|
// that can be used in `os.Exit` to exit immediately when the function returns.
|
|
|
|
// The special exit code `-1` is used if execution was interrupted.
|
|
|
|
func syncAndStopNode(interruptCh <-chan struct{}, nodeManager common.NodeManager, timeout int) (exitCode int) {
|
|
|
|
log.Printf("syncAndStopNode: node will synchronize the chain and exit (timeout %d mins)", timeout)
|
|
|
|
|
|
|
|
ctx, cancel := createContextFromTimeout(timeout)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
doneSync := make(chan struct{})
|
|
|
|
errSync := make(chan error)
|
|
|
|
go func() {
|
|
|
|
if err := nodeManager.EnsureSync(ctx); err != nil {
|
|
|
|
errSync <- err
|
|
|
|
}
|
|
|
|
close(doneSync)
|
|
|
|
}()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case err := <-errSync:
|
|
|
|
log.Printf("syncAndStopNode: failed to sync the chain: %v", err)
|
|
|
|
exitCode = 1
|
|
|
|
case <-doneSync:
|
|
|
|
case <-interruptCh:
|
|
|
|
// cancel context and return immediately if interrupted
|
|
|
|
// `-1` is used as a special exit code to denote interruption
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
2018-02-09 13:37:56 +00:00
|
|
|
if err := nodeManager.StopNode(); err != nil {
|
2018-02-08 08:51:53 +00:00
|
|
|
log.Printf("syncAndStopNode: failed to stop the node: %v", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|