daemon: rework stopping
The CLI stop() command can now also stop the GUI.
This commit is contained in:
@@ -487,8 +487,8 @@ class Daemon(Logger):
|
||||
if self.config.get('use_gossip', False):
|
||||
self.network.start_gossip()
|
||||
|
||||
self.stopping_soon = threading.Event()
|
||||
self.stopped_event = asyncio.Event()
|
||||
self._stopping_soon = threading.Event()
|
||||
self._stopped_event = threading.Event()
|
||||
self.taskgroup = TaskGroup()
|
||||
asyncio.run_coroutine_threadsafe(self._run(jobs=daemon_jobs), self.asyncio_loop)
|
||||
|
||||
@@ -507,7 +507,7 @@ class Daemon(Logger):
|
||||
self.logger.exception("taskgroup died.")
|
||||
finally:
|
||||
self.logger.info("taskgroup stopped.")
|
||||
self.stopping_soon.set()
|
||||
await self.stop()
|
||||
|
||||
def load_wallet(self, path, password, *, manual_upgrades=True) -> Optional[Abstract_Wallet]:
|
||||
path = standardize_path(path)
|
||||
@@ -571,41 +571,35 @@ class Daemon(Logger):
|
||||
|
||||
def run_daemon(self):
|
||||
try:
|
||||
self.stopping_soon.wait()
|
||||
self._stopping_soon.wait()
|
||||
except KeyboardInterrupt:
|
||||
self.stopping_soon.set()
|
||||
self.on_stop()
|
||||
asyncio.run_coroutine_threadsafe(self.stop(), self.asyncio_loop).result()
|
||||
self._stopped_event.wait()
|
||||
|
||||
async def stop(self):
|
||||
self.stopping_soon.set()
|
||||
await self.stopped_event.wait()
|
||||
|
||||
def on_stop(self):
|
||||
if self._stopping_soon.is_set():
|
||||
return
|
||||
self._stopping_soon.set()
|
||||
self.logger.info("stop() entered. initiating shutdown")
|
||||
try:
|
||||
self.logger.info("on_stop() entered. initiating shutdown")
|
||||
if self.gui_object:
|
||||
self.gui_object.stop()
|
||||
|
||||
async def stop_async():
|
||||
self.logger.info("stopping all wallets")
|
||||
self.logger.info("stopping all wallets")
|
||||
async with TaskGroup() as group:
|
||||
for k, wallet in self._wallets.items():
|
||||
await group.spawn(wallet.stop())
|
||||
self.logger.info("stopping network and taskgroup")
|
||||
async with ignore_after(2):
|
||||
async with TaskGroup() as group:
|
||||
for k, wallet in self._wallets.items():
|
||||
await group.spawn(wallet.stop())
|
||||
self.logger.info("stopping network and taskgroup")
|
||||
async with ignore_after(2):
|
||||
async with TaskGroup() as group:
|
||||
if self.network:
|
||||
await group.spawn(self.network.stop(full_shutdown=True))
|
||||
await group.spawn(self.taskgroup.cancel_remaining())
|
||||
|
||||
fut = asyncio.run_coroutine_threadsafe(stop_async(), self.asyncio_loop)
|
||||
fut.result()
|
||||
if self.network:
|
||||
await group.spawn(self.network.stop(full_shutdown=True))
|
||||
await group.spawn(self.taskgroup.cancel_remaining())
|
||||
finally:
|
||||
if self.listen_jsonrpc:
|
||||
self.logger.info("removing lockfile")
|
||||
remove_lockfile(get_lockfile(self.config))
|
||||
self.logger.info("stopped")
|
||||
self.asyncio_loop.call_soon_threadsafe(self.stopped_event.set)
|
||||
self._stopped_event.set()
|
||||
|
||||
def run_gui(self, config, plugins):
|
||||
threading.current_thread().setName('GUI')
|
||||
@@ -616,10 +610,14 @@ class Daemon(Logger):
|
||||
try:
|
||||
gui = __import__('electrum.gui.' + gui_name, fromlist=['electrum'])
|
||||
self.gui_object = gui.ElectrumGui(config, self, plugins)
|
||||
self.gui_object.main()
|
||||
if not self._stopping_soon.is_set():
|
||||
self.gui_object.main()
|
||||
else:
|
||||
# If daemon.stop() was called before gui_object got created, stop gui now.
|
||||
self.gui_object.stop()
|
||||
except BaseException as e:
|
||||
self.logger.error(f'GUI raised exception: {repr(e)}. shutting down.')
|
||||
raise
|
||||
finally:
|
||||
# app will exit now
|
||||
self.on_stop()
|
||||
asyncio.run_coroutine_threadsafe(self.stop(), self.asyncio_loop).result()
|
||||
|
||||
Reference in New Issue
Block a user