@@ -22,25 +22,61 @@ type Node interface {
2222 // Run initiates all common components (logger, database, protocol state etc.)
2323 // then starts each component. It also sets up a channel to gracefully shut
2424 // down each component if a SIGINT is received.
25- Run ()
25+ // The context can also be used to signal the node to shutdown.
26+ Run (ctx context.Context )
2627}
2728
2829// FlowNodeImp is created by the FlowNodeBuilder with all components ready to be started.
2930// The Run function starts all the components, and is blocked until either a termination
3031// signal is received or a irrecoverable error is encountered.
3132type FlowNodeImp struct {
32- component. Component
33+ NodeImp
3334 * NodeConfig
35+ }
36+
37+ // NodeImp can be used to create a node instance from:
38+ // - a logger: to be used during startup and shutdown
39+ // - a component: that will be started with Run
40+ // - a cleanup function: that will be called after the component has been stopped
41+ // - a fatal error handler: to handle any error received from the component
42+ type NodeImp struct {
43+ component.Component
3444 logger zerolog.Logger
3545 postShutdown func () error
3646 fatalHandler func (error )
3747}
3848
3949// NewNode returns a new node instance
40- func NewNode (component component.Component , cfg * NodeConfig , logger zerolog.Logger , cleanup func () error , handleFatal func (error )) Node {
50+ func NewNode (
51+ component component.Component ,
52+ cfg * NodeConfig ,
53+ logger zerolog.Logger ,
54+ cleanup func () error ,
55+ handleFatal func (error ),
56+ ) Node {
4157 return & FlowNodeImp {
58+ NodeConfig : cfg ,
59+ NodeImp : NewBaseNode (
60+ component ,
61+ logger .With ().
62+ Str ("node_role" , cfg .BaseConfig .NodeRole ).
63+ Hex ("spork_id" , logging .ID (cfg .SporkID )).
64+ Logger (),
65+ cleanup ,
66+ handleFatal ,
67+ ),
68+ }
69+ }
70+
71+ // NewBaseNode returns a new base node instance
72+ func NewBaseNode (
73+ component component.Component ,
74+ logger zerolog.Logger ,
75+ cleanup func () error ,
76+ handleFatal func (error ),
77+ ) NodeImp {
78+ return NodeImp {
4279 Component : component ,
43- NodeConfig : cfg ,
4480 logger : logger ,
4581 postShutdown : cleanup ,
4682 fatalHandler : handleFatal ,
@@ -51,13 +87,10 @@ func NewNode(component component.Component, cfg *NodeConfig, logger zerolog.Logg
5187// which point it gracefully shuts down.
5288// Any unhandled irrecoverable errors thrown in child components will propagate up to here and
5389// result in a fatal error.
54- func (node * FlowNodeImp ) Run () {
55- // Cancelling this context notifies all child components that it's time to shutdown
56- ctx , cancel := context .WithCancel (context .Background ())
57- defer cancel ()
90+ func (node * NodeImp ) Run (ctx context.Context ) {
5891
5992 // Block until node is shutting down
60- err := node .run (ctx , cancel )
93+ err := node .run (ctx )
6194
6295 // Any error received is considered fatal.
6396 if err != nil {
@@ -73,14 +106,18 @@ func (node *FlowNodeImp) Run() {
73106 node .logger .Error ().Err (err ).Msg ("error encountered during cleanup" )
74107 }
75108
76- node .logger .Info ().Msgf ( "%s node shutdown complete", node . BaseConfig . NodeRole )
109+ node .logger .Info ().Msg ( " node shutdown complete" )
77110}
78111
79112// run starts the node and blocks until a SIGINT/SIGTERM is received or an error is encountered.
80113// It returns:
81114// - nil if a termination signal is received, and all components have been gracefully stopped.
82- // - error if a irrecoverable error is received
83- func (node * FlowNodeImp ) run (ctx context.Context , shutdown context.CancelFunc ) error {
115+ // - error if an irrecoverable error is received
116+ func (node * NodeImp ) run (ctx context.Context ) error {
117+ // Cancelling this context notifies all child components that it's time to shut down
118+ ctx , shutdown := context .WithCancel (ctx )
119+ defer shutdown ()
120+
84121 // Components will pass unhandled irrecoverable errors to this channel via signalerCtx (or a
85122 // child context). Any errors received on this channel should halt the node.
86123 signalerCtx , errChan := irrecoverable .WithSignaler (ctx )
@@ -97,8 +134,7 @@ func (node *FlowNodeImp) run(ctx context.Context, shutdown context.CancelFunc) e
97134 select {
98135 case <- node .Ready ():
99136 node .logger .Info ().
100- Hex ("spork_id" , logging .ID (node .SporkID )).
101- Msgf ("%s node startup complete" , node .BaseConfig .NodeRole )
137+ Msg ("node startup complete" )
102138 case <- ctx .Done ():
103139 }
104140 }()
@@ -118,7 +154,7 @@ func (node *FlowNodeImp) run(ctx context.Context, shutdown context.CancelFunc) e
118154
119155 // 3: Shut down
120156 // Send shutdown signal to components
121- node .logger .Info ().Msgf ( "%s node shutting down", node . BaseConfig . NodeRole )
157+ node .logger .Info ().Msg ( " node shutting down" )
122158 shutdown ()
123159
124160 // Block here until all components have stopped or an irrecoverable error is received.
0 commit comments