Skip to content

Commit

Permalink
fix gui: stop daemon gracefully
Browse files Browse the repository at this point in the history
  • Loading branch information
edouardparis committed Aug 22, 2023
1 parent 8dd4710 commit 63a221a
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 127 deletions.
18 changes: 6 additions & 12 deletions gui/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use state::{

use crate::{
app::{cache::Cache, error::Error, menu::Menu, wallet::Wallet},
daemon::Daemon,
daemon::{embedded::EmbeddedDaemon, Daemon},
};

pub struct App {
Expand Down Expand Up @@ -113,11 +113,8 @@ impl App {
pub fn stop(&mut self) {
info!("Close requested");
if !self.daemon.is_external() {
info!("Stopping internal daemon...");
if let Some(d) = Arc::get_mut(&mut self.daemon) {
d.stop().expect("Daemon is internal");
info!("Internal daemon stopped");
}
self.daemon.stop();
info!("Internal daemon stopped");
}
}

Expand Down Expand Up @@ -171,12 +168,9 @@ impl App {
daemon_config_path: &PathBuf,
cfg: DaemonConfig,
) -> Result<(), Error> {
loop {
if let Some(daemon) = Arc::get_mut(&mut self.daemon) {
daemon.load_config(cfg)?;
break;
}
}
self.daemon.stop();
let daemon = EmbeddedDaemon::start(cfg)?;
self.daemon = Arc::new(daemon);

let mut daemon_config_file = OpenOptions::new()
.write(true)
Expand Down
5 changes: 2 additions & 3 deletions gui/src/daemon/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ impl<C: Client + Debug> Daemon for Lianad<C> {
None
}

fn stop(&mut self) -> Result<(), DaemonError> {
let _res: serde_json::value::Value = self.call("stop", Option::<Request>::None)?;
Ok(())
fn stop(&self) {
unreachable!("GUI should not ask external client to stop")
}

fn get_info(&self) -> Result<GetInfoResult, DaemonError> {
Expand Down
116 changes: 15 additions & 101 deletions gui/src/daemon/embedded.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::collections::HashMap;
use std::sync::RwLock;

use super::{model::*, Daemon, DaemonError};
use liana::{
Expand All @@ -10,22 +9,13 @@ use liana::{

pub struct EmbeddedDaemon {
config: Config,
handle: Option<RwLock<DaemonHandle>>,
handle: DaemonHandle,
}

impl EmbeddedDaemon {
pub fn new(config: Config) -> Self {
Self {
config,
handle: None,
}
}

pub fn start(&mut self) -> Result<(), DaemonError> {
let handle =
DaemonHandle::start_default(self.config.clone()).map_err(DaemonError::Start)?;
self.handle = Some(RwLock::new(handle));
Ok(())
pub fn start(config: Config) -> Result<EmbeddedDaemon, DaemonError> {
let handle = DaemonHandle::start_default(config.clone()).map_err(DaemonError::Start)?;
Ok(Self { handle, config })
}
}

Expand All @@ -40,71 +30,32 @@ impl Daemon for EmbeddedDaemon {
false
}

fn load_config(&mut self, cfg: Config) -> Result<(), DaemonError> {
if self.handle.is_none() {
return Ok(());
}

let next = DaemonHandle::start_default(cfg).map_err(DaemonError::Start)?;
self.handle.take().unwrap().into_inner().unwrap().shutdown();
self.handle = Some(RwLock::new(next));
Ok(())
}

fn config(&self) -> Option<&Config> {
Some(&self.config)
}

fn stop(&mut self) -> Result<(), DaemonError> {
if let Some(h) = self.handle.take() {
let handle = h.into_inner().unwrap();
handle.shutdown();
fn stop(&self) {
self.handle.trigger_shutdown();
while !self.handle.shutdown_complete() {
tracing::debug!("Waiting daemon to shutdown");
std::thread::sleep(std::time::Duration::from_millis(500));
}
Ok(())
}

fn get_info(&self) -> Result<GetInfoResult, DaemonError> {
Ok(self
.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.get_info())
Ok(self.handle.control.get_info())
}

fn get_new_address(&self) -> Result<GetAddressResult, DaemonError> {
Ok(self
.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.get_new_address())
Ok(self.handle.control.get_new_address())
}

fn list_coins(&self) -> Result<ListCoinsResult, DaemonError> {
Ok(self
.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.list_coins())
Ok(self.handle.control.list_coins())
}

fn list_spend_txs(&self) -> Result<ListSpendResult, DaemonError> {
Ok(self
.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.list_spend())
Ok(self.handle.control.list_spend())
}

fn list_confirmed_txs(
Expand All @@ -115,23 +66,12 @@ impl Daemon for EmbeddedDaemon {
) -> Result<ListTransactionsResult, DaemonError> {
Ok(self
.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.list_confirmed_transactions(start, end, limit))
}

fn list_txs(&self, txids: &[Txid]) -> Result<ListTransactionsResult, DaemonError> {
Ok(self
.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.list_transactions(txids))
Ok(self.handle.control.list_transactions(txids))
}

fn create_spend_tx(
Expand All @@ -141,54 +81,32 @@ impl Daemon for EmbeddedDaemon {
feerate_vb: u64,
) -> Result<CreateSpendResult, DaemonError> {
self.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.create_spend(destinations, coins_outpoints, feerate_vb)
.map_err(|e| DaemonError::Unexpected(e.to_string()))
}

fn update_spend_tx(&self, psbt: &Psbt) -> Result<(), DaemonError> {
self.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.update_spend(psbt.clone())
.map_err(|e| DaemonError::Unexpected(e.to_string()))
}

fn delete_spend_tx(&self, txid: &Txid) -> Result<(), DaemonError> {
self.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.delete_spend(txid);
self.handle.control.delete_spend(txid);
Ok(())
}

fn broadcast_spend_tx(&self, txid: &Txid) -> Result<(), DaemonError> {
self.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.broadcast_spend(txid)
.map_err(|e| DaemonError::Unexpected(e.to_string()))
}

fn start_rescan(&self, t: u32) -> Result<(), DaemonError> {
self.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.start_rescan(t)
.map_err(|e| DaemonError::Unexpected(e.to_string()))
Expand All @@ -201,10 +119,6 @@ impl Daemon for EmbeddedDaemon {
sequence: Option<u16>,
) -> Result<Psbt, DaemonError> {
self.handle
.as_ref()
.ok_or(DaemonError::NoAnswer)?
.read()
.unwrap()
.control
.create_recovery(address, feerate_vb, sequence)
.map_err(|e| DaemonError::Unexpected(e.to_string()))
Expand Down
5 changes: 1 addition & 4 deletions gui/src/daemon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,8 @@ impl std::fmt::Display for DaemonError {

pub trait Daemon: Debug {
fn is_external(&self) -> bool;
fn load_config(&mut self, _cfg: Config) -> Result<(), DaemonError> {
Ok(())
}
fn config(&self) -> Option<&Config>;
fn stop(&mut self) -> Result<(), DaemonError>;
fn stop(&self);
fn get_info(&self) -> Result<model::GetInfoResult, DaemonError>;
fn get_new_address(&self) -> Result<model::GetAddressResult, DaemonError>;
fn list_coins(&self) -> Result<model::ListCoinsResult, DaemonError>;
Expand Down
10 changes: 3 additions & 7 deletions gui/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,8 @@ impl Loader {
if let Step::Syncing { daemon, .. } = &mut self.step {
if !daemon.is_external() {
info!("Stopping internal daemon...");
if let Some(d) = Arc::get_mut(daemon) {
d.stop().expect("Daemon is internal");
info!("Internal daemon stopped");
} else {
}
daemon.stop();
info!("Internal daemon stopped");
}
}
}
Expand Down Expand Up @@ -335,8 +332,7 @@ pub async fn start_daemon(config_path: PathBuf) -> Result<Arc<dyn Daemon + Sync

let config = Config::from_file(Some(config_path)).map_err(Error::Config)?;

let mut daemon = EmbeddedDaemon::new(config);
daemon.start()?;
let daemon = EmbeddedDaemon::start(config)?;

Ok(Arc::new(daemon))
}
Expand Down

0 comments on commit 63a221a

Please sign in to comment.