feat: Kill monero-wallet-rpc on GUI exit

This commit is contained in:
binarybaron 2024-08-09 23:34:21 +02:00
parent acdb0231b5
commit 718132b8b4
No known key found for this signature in database
GPG key ID: 99B75D3E1476A26E
3 changed files with 37 additions and 10 deletions

View file

@ -11,7 +11,7 @@ use swap::{
}, },
cli::command::{Bitcoin, Monero}, cli::command::{Bitcoin, Monero},
}; };
use tauri::{Manager, State}; use tauri::{Manager, RunEvent, State};
trait ToStringResult<T> { trait ToStringResult<T> {
fn to_string_result(self) -> Result<T, String>; fn to_string_result(self) -> Result<T, String>;
@ -107,6 +107,16 @@ pub fn run() {
withdraw_btc withdraw_btc
]) ])
.setup(setup) .setup(setup)
.run(tauri::generate_context!()) .build(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while building tauri application")
.run(|app, event| match event {
RunEvent::Exit | RunEvent::ExitRequested { .. } => {
let context = app.state::<Arc<Context>>().inner();
if let Err(err) = context.cleanup() {
println!("Cleanup failed {}", err);
}
}
_ => {}
})
} }

View file

@ -7,14 +7,14 @@ use crate::network::rendezvous::XmrBtcNamespace;
use crate::protocol::Database; use crate::protocol::Database;
use crate::seed::Seed; use crate::seed::Seed;
use crate::{bitcoin, cli, monero}; use crate::{bitcoin, cli, monero};
use anyhow::{bail, Context as AnyContext, Error, Result}; use anyhow::{anyhow, bail, Context as AnyContext, Error, Result};
use futures::future::try_join_all; use futures::future::try_join_all;
use std::fmt; use std::fmt;
use std::future::Future; use std::future::Future;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Once}; use std::sync::{Arc, Mutex, Once};
use tokio::sync::{broadcast, broadcast::Sender, Mutex, RwLock}; use tokio::sync::{broadcast, broadcast::Sender, Mutex as TokioMutex, RwLock};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use url::Url; use url::Url;
@ -36,7 +36,7 @@ pub struct Config {
use uuid::Uuid; use uuid::Uuid;
#[derive(Default)] #[derive(Default)]
pub struct PendingTaskList(Mutex<Vec<JoinHandle<()>>>); pub struct PendingTaskList(TokioMutex<Vec<JoinHandle<()>>>);
impl PendingTaskList { impl PendingTaskList {
pub async fn spawn<F, T>(&self, future: F) pub async fn spawn<F, T>(&self, future: F)
@ -164,7 +164,7 @@ pub struct Context {
pub db: Arc<dyn Database + Send + Sync>, pub db: Arc<dyn Database + Send + Sync>,
bitcoin_wallet: Option<Arc<bitcoin::Wallet>>, bitcoin_wallet: Option<Arc<bitcoin::Wallet>>,
monero_wallet: Option<Arc<monero::Wallet>>, monero_wallet: Option<Arc<monero::Wallet>>,
monero_rpc_process: Option<Arc<monero::WalletRpcProcess>>, monero_rpc_process: Option<Arc<Mutex<monero::WalletRpcProcess>>>,
pub swap_lock: Arc<SwapLock>, pub swap_lock: Arc<SwapLock>,
pub config: Config, pub config: Config,
pub tasks: Arc<PendingTaskList>, pub tasks: Arc<PendingTaskList>,
@ -228,7 +228,7 @@ impl Context {
db: open_db(data_dir.join("sqlite")).await?, db: open_db(data_dir.join("sqlite")).await?,
bitcoin_wallet, bitcoin_wallet,
monero_wallet, monero_wallet,
monero_rpc_process: monero_rpc_process.map(Arc::new), monero_rpc_process: monero_rpc_process.map(|prc| Arc::new(Mutex::new(prc))),
config: Config { config: Config {
tor_socks5_port, tor_socks5_port,
namespace: XmrBtcNamespace::from_is_testnet(is_testnet), namespace: XmrBtcNamespace::from_is_testnet(is_testnet),
@ -268,6 +268,19 @@ impl Context {
tasks: Arc::new(PendingTaskList::default()), tasks: Arc::new(PendingTaskList::default()),
} }
} }
pub fn cleanup(&self) -> Result<()> {
if let Some(ref monero_rpc_process) = self.monero_rpc_process {
let mut process = monero_rpc_process
.lock()
.map_err(|_| anyhow!("Failed to lock monero_rpc_process for cleanup"))?;
process.kill()?;
println!("Killed monero-wallet-rpc process");
}
Ok(())
}
} }
impl fmt::Debug for Context { impl fmt::Debug for Context {

View file

@ -8,12 +8,12 @@ use reqwest::header::CONTENT_LENGTH;
use reqwest::Url; use reqwest::Url;
use serde::Deserialize; use serde::Deserialize;
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use std::fmt;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::io::ErrorKind; use std::io::ErrorKind;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Stdio; use std::process::Stdio;
use std::time::Duration; use std::time::Duration;
use std::{fmt, io};
use tokio::fs::{remove_file, OpenOptions}; use tokio::fs::{remove_file, OpenOptions};
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::process::{Child, Command}; use tokio::process::{Child, Command};
@ -178,6 +178,10 @@ impl WalletRpcProcess {
Url::parse(&format!("http://127.0.0.1:{}/json_rpc", self.port)) Url::parse(&format!("http://127.0.0.1:{}/json_rpc", self.port))
.expect("Static url template is always valid") .expect("Static url template is always valid")
} }
pub fn kill(&mut self) -> io::Result<()> {
self._child.start_kill()
}
} }
pub struct WalletRpc { pub struct WalletRpc {