-
Notifications
You must be signed in to change notification settings - Fork 53
/
main.go
102 lines (92 loc) · 2.79 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package main
import (
"context"
"fmt"
"go/build"
"os"
"os/signal"
"syscall"
"time"
"github.com/ava-labs/avalanche-network-runner/local"
"github.com/ava-labs/avalanche-network-runner/network"
"github.com/ava-labs/avalanchego/utils/logging"
"go.uber.org/zap"
)
const (
healthyTimeout = 2 * time.Minute
)
var goPath = os.ExpandEnv("$GOPATH")
// Blocks until a signal is received on [signalChan], upon which
// [n.Stop()] is called. If [signalChan] is closed, does nothing.
// Closes [closedOnShutdownChan] amd [signalChan] when done shutting down network.
// This function should only be called once.
func shutdownOnSignal(
log logging.Logger,
n network.Network,
signalChan chan os.Signal,
closedOnShutdownChan chan struct{},
) {
sig := <-signalChan
log.Info("got OS signal", zap.Stringer("signal", sig))
if err := n.Stop(context.Background()); err != nil {
log.Info("error stopping network", zap.Error(err))
}
signal.Reset()
close(signalChan)
close(closedOnShutdownChan)
}
// Shows example usage of the Avalanche Network Runner.
// Creates a local five node Avalanche network
// and waits for all nodes to become healthy.
// The network runs until the user provides a SIGINT or SIGTERM.
func main() {
// Create the logger
logFactory := logging.NewFactory(logging.Config{
DisplayLevel: logging.Info,
LogLevel: logging.Debug,
})
log, err := logFactory.Make("main")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if goPath == "" {
goPath = build.Default.GOPATH
}
binaryPath := fmt.Sprintf("%s%s", goPath, "/src/github.com/ava-labs/avalanchego/build/avalanchego")
if err := run(log, binaryPath); err != nil {
log.Fatal("fatal error", zap.Error(err))
os.Exit(1)
}
}
func run(log logging.Logger, binaryPath string) error {
// Create the network
nw, err := local.NewDefaultNetwork(log, binaryPath, true, true, true)
if err != nil {
return err
}
defer func() { // Stop the network when this function returns
if err := nw.Stop(context.Background()); err != nil {
log.Info("error stopping network", zap.Error(err))
}
}()
// When we get a SIGINT or SIGTERM, stop the network and close [closedOnShutdownCh]
signalsChan := make(chan os.Signal, 1)
signal.Notify(signalsChan, syscall.SIGINT)
signal.Notify(signalsChan, syscall.SIGTERM)
closedOnShutdownCh := make(chan struct{})
go func() {
shutdownOnSignal(log, nw, signalsChan, closedOnShutdownCh)
}()
// Wait until the nodes in the network are ready
ctx, cancel := context.WithTimeout(context.Background(), healthyTimeout)
defer cancel()
log.Info("waiting for all nodes to report healthy...")
if err := nw.Healthy(ctx); err != nil {
return err
}
log.Info("All nodes healthy. Network will run until you CTRL + C to exit...")
// Wait until done shutting down network after SIGINT/SIGTERM
<-closedOnShutdownCh
return nil
}