Skip to content

Commit ab91ede

Browse files
committed
multi: track LiT and LND status
With this commit, we now also track the start-up state of LiT and LiT's connection to LND. These differ from the other sub-servers (loop, pool & faraday) because a failure to start LiT or LND is fatal and so should stop the rest of the start-process, however, we still want the webserver to continue serving the new Status server so that the UI can query the start-up status of LND and LiT. So: if any errors occur while starting/connecting to LND or any other errors occur while starting any of LiTs other processes, then we throw an error but we dont kill the main LiT process. The main process is only killed upon receiving a shutdown signal.
1 parent 4d53fa3 commit ab91ede

File tree

2 files changed

+88
-47
lines changed

2 files changed

+88
-47
lines changed

rpc_proxy.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,10 @@ func (p *rpcProxy) checkSubSystemStarted(requestURI string) error {
421421
system = subServerName
422422

423423
case p.permsMgr.IsLndURI(requestURI):
424-
return nil
424+
system = LNDSubServer
425425

426426
case p.permsMgr.IsLitURI(requestURI):
427-
return nil
427+
system = LitSubServer
428428

429429
default:
430430
return fmt.Errorf("unknown gRPC web request: %v", requestURI)

terminal.go

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,53 @@ func (g *LightningTerminal) Run() error {
222222
return fmt.Errorf("error starting UI HTTP server: %v", err)
223223
}
224224

225+
// Attempt to start Lit and all of its sub-servers. If an error is
226+
// returned, it means that either one of Lit's sub-servers internal could not
227+
// start or LND
228+
startErr := g.start()
229+
if startErr != nil {
230+
g.statusServer.setServerErrored(
231+
LitSubServer, "could not start Lit: %v", startErr,
232+
)
233+
}
234+
235+
// Now block until we receive an error or the main shutdown
236+
// signal.
237+
<-shutdownInterceptor.ShutdownChannel()
238+
log.Infof("Shutdown signal received")
239+
240+
if g.rpcProxy != nil {
241+
if err := g.rpcProxy.Stop(); err != nil {
242+
log.Errorf("Error stopping rpc proxy: %v", err)
243+
}
244+
}
245+
246+
if g.httpServer != nil {
247+
if err := g.httpServer.Close(); err != nil {
248+
log.Errorf("Error stopping UI server: %v", err)
249+
}
250+
}
251+
252+
if err := g.statusServer.Stop(); err != nil {
253+
log.Errorf("Error stopping status server: %v", err)
254+
}
255+
256+
g.wg.Wait()
257+
258+
return startErr
259+
}
260+
261+
// start attempts to start all the various components of Litd. Only Litd and
262+
// LND errors are considered fatal and will result in an error being returned.
263+
// If any of the sub-servers managed by the subServerMgr error while starting
264+
// up, these are considered non-fatal and will not result in an error being
265+
// returned.
266+
func (g *LightningTerminal) start() error {
225267
// Create the instances of our subservers now so we can hook them up to
226268
// lnd once it's fully running.
227269
g.initSubServers()
228270

271+
var err error
229272
g.sessionRpcServer, err = newSessionRPCServer(&sessionRpcServerConfig{
230273
basicAuth: g.rpcProxy.basicAuth,
231274
dbDir: filepath.Join(g.cfg.LitDir, g.cfg.Network),
@@ -300,9 +343,7 @@ func (g *LightningTerminal) Run() error {
300343
go func() {
301344
defer g.wg.Done()
302345

303-
err := lnd.Main(
304-
g.cfg.Lnd, lisCfg, implCfg, shutdownInterceptor,
305-
)
346+
err := lnd.Main(g.cfg.Lnd, lisCfg, implCfg, interceptor)
306347
if e, ok := err.(*flags.Error); err != nil &&
307348
(!ok || e.Type != flags.ErrHelp) {
308349

@@ -341,27 +382,36 @@ func (g *LightningTerminal) Run() error {
341382
case <-readyChan:
342383

343384
case err := <-g.errQueue.ChanOut():
344-
return err
385+
g.statusServer.setServerErrored(
386+
LNDSubServer, "error from errQueue channel",
387+
)
388+
return fmt.Errorf("could not start LND: %v", err)
345389

346390
case <-lndQuit:
347-
return nil
391+
g.statusServer.setServerErrored(
392+
LNDSubServer, "lndQuit channel closed",
393+
)
394+
return fmt.Errorf("LND has stopped")
348395

349-
case <-shutdownInterceptor.ShutdownChannel():
350-
return errors.New("shutting down")
396+
case <-interceptor.ShutdownChannel():
397+
return fmt.Errorf("received the shutdown signal")
351398
}
352399

353400
// We now know that starting lnd was successful. If we now run into an
354401
// error, we must shut down lnd correctly.
355402
defer func() {
356-
err := g.shutdown()
403+
err := g.shutdownSubServers()
357404
if err != nil {
358405
log.Errorf("Error shutting down: %v", err)
359406
}
360407
}()
361408

362409
// Connect to LND.
363410
if err = g.connectLND(bufRpcListener); err != nil {
364-
return fmt.Errorf("could not connect to LND: %v", err)
411+
g.statusServer.setServerErrored(
412+
LNDSubServer, "could not connect to LND: %v", err,
413+
)
414+
return fmt.Errorf("could not connect to LND")
365415
}
366416

367417
// Initialise any connections to sub-servers that we are running in
@@ -389,12 +439,18 @@ func (g *LightningTerminal) Run() error {
389439
return err
390440

391441
case <-lndQuit:
392-
return nil
442+
g.statusServer.setServerErrored(
443+
LNDSubServer, "lndQuit channel closed",
444+
)
445+
return fmt.Errorf("LND is not running")
393446

394-
case <-shutdownInterceptor.ShutdownChannel():
447+
case <-interceptor.ShutdownChannel():
395448
return errors.New("shutting down")
396449
}
397450

451+
// We can now set the status of LND as running.
452+
g.statusServer.setServerRunning(LNDSubServer)
453+
398454
// If we're in integrated mode, we'll need to wait for lnd to send the
399455
// macaroon after unlock before going any further.
400456
if g.cfg.LndMode == ModeIntegrated {
@@ -405,8 +461,10 @@ func (g *LightningTerminal) Run() error {
405461
// Set up all the LND clients required by LiT.
406462
err = g.setUpLNDClients()
407463
if err != nil {
408-
log.Errorf("Could not set up LND clients: %v", err)
409-
return err
464+
g.statusServer.setServerErrored(
465+
LNDSubServer, "could not set up LND clients: %v", err,
466+
)
467+
return fmt.Errorf("could not start LND")
410468
}
411469

412470
// If we're in integrated and stateless init mode, we won't create
@@ -433,22 +491,28 @@ func (g *LightningTerminal) Run() error {
433491
return fmt.Errorf("could not start litd sub-servers: %v", err)
434492
}
435493

494+
// We can now set the status of LiT as running.
495+
g.statusServer.setServerRunning(LitSubServer)
496+
436497
// Now block until we receive an error or the main shutdown signal.
437498
select {
438499
case err := <-g.errQueue.ChanOut():
439500
if err != nil {
440-
log.Errorf("Received critical error from subsystem, "+
441-
"shutting down: %v", err)
501+
return fmt.Errorf("received critical error from "+
502+
"subsystem, shutting down: %v", err,
503+
)
442504
}
443505

444506
case <-lndQuit:
445-
return nil
507+
g.statusServer.setServerErrored(
508+
LNDSubServer, "lndQuit channel closed",
509+
)
510+
return fmt.Errorf("LND is not running")
446511

447-
case <-shutdownInterceptor.ShutdownChannel():
448-
log.Infof("Shutdown signal received")
512+
case <-interceptor.ShutdownChannel():
449513
}
450514

451-
return nil
515+
return fmt.Errorf("received the shutdown signal")
452516
}
453517

454518
// initSubServers registers the faraday, loop and pool sub-servers with the
@@ -899,8 +963,9 @@ func (g *LightningTerminal) BuildWalletConfig(ctx context.Context,
899963
)
900964
}
901965

902-
// shutdown stops all subservers that were started and attached to lnd.
903-
func (g *LightningTerminal) shutdown() error {
966+
// shutdownSubServers stops all subservers that were started and attached to
967+
// lnd.
968+
func (g *LightningTerminal) shutdownSubServers() error {
904969
var returnErr error
905970

906971
err := g.subServerMgr.Stop()
@@ -934,37 +999,13 @@ func (g *LightningTerminal) shutdown() error {
934999
g.restCancel()
9351000
}
9361001

937-
if g.rpcProxy != nil {
938-
if err := g.rpcProxy.Stop(); err != nil {
939-
log.Errorf("Error stopping lnd proxy: %v", err)
940-
returnErr = err
941-
}
942-
}
943-
9441002
if g.lndConn != nil {
9451003
if err := g.lndConn.Close(); err != nil {
9461004
log.Errorf("Error closing lnd connection: %v", err)
9471005
returnErr = err
9481006
}
9491007
}
9501008

951-
if g.httpServer != nil {
952-
if err := g.httpServer.Close(); err != nil {
953-
log.Errorf("Error stopping UI server: %v", err)
954-
returnErr = err
955-
}
956-
}
957-
958-
if err := g.statusServer.Stop(); err != nil {
959-
log.Errorf("Error stopping status server: %v", err)
960-
returnErr = err
961-
}
962-
963-
// In case the error wasn't thrown by lnd, make sure we stop it too.
964-
interceptor.RequestShutdown()
965-
966-
g.wg.Wait()
967-
9681009
// Do we have any last errors to display? We use an anonymous function,
9691010
// so we can use return instead of breaking to a label in the default
9701011
// case.

0 commit comments

Comments
 (0)