Attempt a last-ditch ChannelManager persistence if the BP exits
[ldk-sample] / src / main.rs
index 2012921c334f6a6930693899c11a7549574df601..3f01cfe26a2d35ef49cd456c634c282a8af152a9 100644 (file)
@@ -802,7 +802,7 @@ async fn start_ldk() {
 
        // Step 20: Background Processing
        let (bp_exit, bp_exit_check) = tokio::sync::watch::channel(());
-       let background_processor = tokio::spawn(process_events_async(
+       let mut background_processor = tokio::spawn(process_events_async(
                Arc::clone(&persister),
                event_handler,
                chain_monitor.clone(),
@@ -898,7 +898,7 @@ async fn start_ldk() {
        ));
 
        // Start the CLI.
-       cli::poll_for_user_input(
+       let cli_poll = tokio::spawn(cli::poll_for_user_input(
                Arc::clone(&peer_manager),
                Arc::clone(&channel_manager),
                Arc::clone(&keys_manager),
@@ -910,17 +910,43 @@ async fn start_ldk() {
                network,
                Arc::clone(&logger),
                Arc::clone(&persister),
-       )
-       .await;
+       ));
+
+       // Exit if either CLI polling exits or the background processor exits (which shouldn't happen
+       // unless we fail to write to the filesystem).
+       let mut bg_res = Ok(Ok(()));
+       tokio::select! {
+               _ = cli_poll => {},
+               bg_exit = &mut background_processor => {
+                       bg_res = bg_exit;
+               },
+       }
 
        // Disconnect our peers and stop accepting new connections. This ensures we don't continue
        // updating our channel data after we've stopped the background processor.
        stop_listen_connect.store(true, Ordering::Release);
        peer_manager.disconnect_all_peers();
 
+       if let Err(e) = bg_res {
+               let persist_res = persister.persist("manager", &*channel_manager).unwrap();
+               use lightning::util::logger::Logger;
+               lightning::log_error!(
+                       &*logger,
+                       "Last-ditch ChannelManager persistence result: {:?}",
+                       persist_res
+               );
+               panic!(
+                       "ERR: background processing stopped with result {:?}, exiting.\n\
+                       Last-ditch ChannelManager persistence result {:?}",
+                       e, persist_res
+               );
+       }
+
        // Stop the background processor.
-       bp_exit.send(()).unwrap();
-       background_processor.await.unwrap().unwrap();
+       if !bp_exit.is_closed() {
+               bp_exit.send(()).unwrap();
+               background_processor.await.unwrap().unwrap();
+       }
 }
 
 #[tokio::main]