Timeout waiting for mutex on shutdown.

This commit is contained in:
tecnovert
2025-04-16 08:30:50 +02:00
parent b293b5daee
commit 21c0a534f2
5 changed files with 32 additions and 18 deletions

View File

@@ -61,7 +61,7 @@ class BaseApp(DBMethods):
self._network = None self._network = None
self.prepareLogging() self.prepareLogging()
self.log.info("Network: {}".format(self.chain)) self.log.info(f"Network: {self.chain}")
self.use_tor_proxy = self.settings.get("use_tor", False) self.use_tor_proxy = self.settings.get("use_tor", False)
self.tor_proxy_host = self.settings.get("tor_proxy_host", "127.0.0.1") self.tor_proxy_host = self.settings.get("tor_proxy_host", "127.0.0.1")
@@ -78,7 +78,14 @@ class BaseApp(DBMethods):
def stopRunning(self, with_code=0): def stopRunning(self, with_code=0):
self.fail_code = with_code self.fail_code = with_code
with self.mxDB:
# Wait for lock to shutdown gracefully.
if self.mxDB.acquire(timeout=5):
self.chainstate_delay_event.set()
self.delay_event.set()
self.mxDB.release()
else:
# Waiting for lock timed out, stop anyway
self.chainstate_delay_event.set() self.chainstate_delay_event.set()
self.delay_event.set() self.delay_event.set()
@@ -143,7 +150,7 @@ class BaseApp(DBMethods):
for c, params in chainparams.items(): for c, params in chainparams.items():
if coin_name.lower() == params["name"].lower(): if coin_name.lower() == params["name"].lower():
return c return c
raise ValueError("Unknown coin: {}".format(coin_name)) raise ValueError(f"Unknown coin: {coin_name}")
def callrpc(self, method, params=[], wallet=None): def callrpc(self, method, params=[], wallet=None):
cc = self.coin_clients[Coins.PART] cc = self.coin_clients[Coins.PART]

View File

@@ -528,9 +528,8 @@ class BasicSwap(BaseApp):
def finalise(self): def finalise(self):
self.log.info("Finalising") self.log.info("Finalising")
with self.mxDB: self.delay_event.set()
self.delay_event.set() self.chainstate_delay_event.set()
self.chainstate_delay_event.set()
if self._network: if self._network:
self._network.stopNetwork() self._network.stopNetwork()
@@ -1182,7 +1181,6 @@ class BasicSwap(BaseApp):
self.stopDaemon(c) self.stopDaemon(c)
def waitForDaemonRPC(self, coin_type, with_wallet: bool = True) -> None: def waitForDaemonRPC(self, coin_type, with_wallet: bool = True) -> None:
if with_wallet: if with_wallet:
self.waitForDaemonRPC(coin_type, with_wallet=False) self.waitForDaemonRPC(coin_type, with_wallet=False)
if coin_type in (Coins.XMR, Coins.WOW): if coin_type in (Coins.XMR, Coins.WOW):
@@ -1206,7 +1204,7 @@ class BasicSwap(BaseApp):
if "startup_tries" in chain_client_settings: if "startup_tries" in chain_client_settings:
startup_tries = chain_client_settings["startup_tries"] startup_tries = chain_client_settings["startup_tries"]
if startup_tries < 1: if startup_tries < 1:
self.log.warning("startup_tries can't be less than 1.") self.log.warning('"startup_tries" can\'t be less than 1.')
startup_tries = 1 startup_tries = 1
for i in range(startup_tries): for i in range(startup_tries):
if self.delay_event.is_set(): if self.delay_event.is_set():

View File

@@ -91,7 +91,7 @@ def startDaemon(node_dir, bin_dir, daemon_bin, opts=[], extra_config={}):
if add_datadir: if add_datadir:
args.append("-datadir=" + datadir_path) args.append("-datadir=" + datadir_path)
args += opts args += opts
logger.info("Starting node {}".format(daemon_bin)) logger.info(f"Starting node {daemon_bin}")
logger.debug("Arguments {}".format(" ".join(args))) logger.debug("Arguments {}".format(" ".join(args)))
opened_files = [] opened_files = []
@@ -137,7 +137,7 @@ def startXmrDaemon(node_dir, bin_dir, daemon_bin, opts=[]):
"--non-interactive", "--non-interactive",
"--config-file=" + os.path.join(datadir_path, config_filename), "--config-file=" + os.path.join(datadir_path, config_filename),
] + opts ] + opts
logger.info("Starting node {}".format(daemon_bin)) logger.info(f"Starting node {daemon_bin}")
logger.debug("Arguments {}".format(" ".join(args))) logger.debug("Arguments {}".format(" ".join(args)))
# return subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # return subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -200,7 +200,7 @@ def startXmrWalletDaemon(node_dir, bin_dir, wallet_bin, opts=[]):
): ):
fp_to.write(line) fp_to.write(line)
logger.info("Starting wallet daemon {}".format(wallet_bin)) logger.info(f"Starting wallet daemon {wallet_bin}")
logger.debug("Arguments {}".format(" ".join(args))) logger.debug("Arguments {}".format(" ".join(args)))
# TODO: return subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=data_dir) # TODO: return subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=data_dir)
@@ -309,7 +309,7 @@ def runClient(
with open(pids_path) as fd: with open(pids_path) as fd:
for ln in fd: for ln in fd:
# TODO: try close # TODO: try close
logger.warning("Found pid for daemon {} ".format(ln.strip())) logger.warning("Found pid for daemon {}".format(ln.strip()))
# Ensure daemons are stopped # Ensure daemons are stopped
swap_client.stopDaemons() swap_client.stopDaemons()
@@ -325,7 +325,7 @@ def runClient(
coin_id = swap_client.getCoinIdFromName(c) coin_id = swap_client.getCoinIdFromName(c)
display_name = getCoinName(coin_id) display_name = getCoinName(coin_id)
except Exception as e: # noqa: F841 except Exception as e: # noqa: F841
logger.warning("Not starting unknown coin: {}".format(c)) logger.warning(f"Not starting unknown coin: {c}")
continue continue
if c in ("monero", "wownero"): if c in ("monero", "wownero"):
if v["manage_daemon"] is True: if v["manage_daemon"] is True:
@@ -334,7 +334,7 @@ def runClient(
daemons.append(startXmrDaemon(v["datadir"], v["bindir"], filename)) daemons.append(startXmrDaemon(v["datadir"], v["bindir"], filename))
pid = daemons[-1].handle.pid pid = daemons[-1].handle.pid
swap_client.log.info("Started {} {}".format(filename, pid)) swap_client.log.info(f"Started {filename} {pid}")
if v["manage_wallet_daemon"] is True: if v["manage_wallet_daemon"] is True:
swap_client.log.info(f"Starting {display_name} wallet daemon") swap_client.log.info(f"Starting {display_name} wallet daemon")
@@ -382,7 +382,7 @@ def runClient(
startXmrWalletDaemon(v["datadir"], v["bindir"], filename, opts) startXmrWalletDaemon(v["datadir"], v["bindir"], filename, opts)
) )
pid = daemons[-1].handle.pid pid = daemons[-1].handle.pid
swap_client.log.info("Started {} {}".format(filename, pid)) swap_client.log.info(f"Started {filename} {pid}")
continue # /monero continue # /monero
@@ -412,7 +412,7 @@ def runClient(
) )
) )
pid = daemons[-1].handle.pid pid = daemons[-1].handle.pid
swap_client.log.info("Started {} {}".format(filename, pid)) swap_client.log.info(f"Started {filename} {pid}")
if v["manage_wallet_daemon"] is True: if v["manage_wallet_daemon"] is True:
swap_client.log.info(f"Starting {display_name} wallet daemon") swap_client.log.info(f"Starting {display_name} wallet daemon")
@@ -457,7 +457,7 @@ def runClient(
pid = daemons[-1].handle.pid pid = daemons[-1].handle.pid
pids.append((c, pid)) pids.append((c, pid))
swap_client.setDaemonPID(c, pid) swap_client.setDaemonPID(c, pid)
swap_client.log.info("Started {} {}".format(filename, pid)) swap_client.log.info(f"Started {filename} {pid}")
if len(pids) > 0: if len(pids) > 0:
with open(pids_path, "w") as fd: with open(pids_path, "w") as fd:
for p in pids: for p in pids:

View File

@@ -401,6 +401,12 @@ class HttpHandler(BaseHTTPRequestHandler):
extra_headers=extra_headers, extra_headers=extra_headers,
) )
def page_shutdown_ping(self, url_split, post_string):
if not self.server.stop_event.is_set():
raise ValueError("Unexpected shutdown ping.")
self.putHeaders(401, "application/json")
return json.dumps({"ack": True}).encode("utf-8")
def page_explorers(self, url_split, post_string): def page_explorers(self, url_split, post_string):
swap_client = self.server.swap_client swap_client = self.server.swap_client
swap_client.checkSystemStatus() swap_client.checkSystemStatus()
@@ -779,6 +785,8 @@ class HttpHandler(BaseHTTPRequestHandler):
if page == "login": if page == "login":
return self.page_login(url_split, post_string) return self.page_login(url_split, post_string)
if page == "shutdown_ping":
return self.page_shutdown_ping(url_split, post_string)
if page == "active": if page == "active":
return self.page_active(url_split, post_string) return self.page_active(url_split, post_string)
if page == "wallets": if page == "wallets":

View File

@@ -166,12 +166,13 @@ def js_wallets(self, url_split, post_string, is_json):
return bytes( return bytes(
json.dumps(swap_client.ci(coin_type).getNewMwebAddress()), "UTF-8" json.dumps(swap_client.ci(coin_type).getNewMwebAddress()), "UTF-8"
) )
raise ValueError("Unknown command") raise ValueError("Unknown command")
if coin_type == Coins.LTC_MWEB: if coin_type == Coins.LTC_MWEB:
coin_type = Coins.LTC coin_type = Coins.LTC
rv = swap_client.getWalletInfo(coin_type) rv = swap_client.getWalletInfo(coin_type)
if not rv:
raise ValueError(f"getWalletInfo failed for coin: {coin_type}")
rv.update(swap_client.getBlockchainInfo(coin_type)) rv.update(swap_client.getBlockchainInfo(coin_type))
ci = swap_client.ci(coin_type) ci = swap_client.ci(coin_type)
checkAddressesOwned(swap_client, ci, rv) checkAddressesOwned(swap_client, ci, rv)