changeset 4142:783bbdbf8567

cli (base): new `a_quit` method to run async cleaning methods: it may be necessary to run some async cleaning method (e.g. if bridge is needed), this new method handles async cleaning method, and will be called when `SystemExit` is used, or if `a_quit` is called explicitely. rel 426
author Goffi <goffi@goffi.org>
date Wed, 01 Nov 2023 14:08:00 +0100
parents ba8ddfdd334f
children 849721e1563b
files libervia/cli/base.py
diffstat 1 files changed, 20 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libervia/cli/base.py	Wed Nov 01 14:05:53 2023 +0100
+++ b/libervia/cli/base.py	Wed Nov 01 14:08:00 2023 +0100
@@ -49,7 +49,7 @@
 from libervia.cli.loops import QuitException, get_libervia_cli_loop
 from libervia.cli.constants import Const as C
 from libervia.frontends.bridge.bridge_frontend import BridgeException
-from libervia.frontends.tools import misc
+from libervia.frontends.tools import aio, misc
 import xml.etree.ElementTree as ET  # FIXME: used temporarily to manage XMLUI
 from collections import OrderedDict
 from rich import console
@@ -733,7 +733,9 @@
         try:
             self.loop.run(self, args, namespace)
         except SystemExit:
-            self.quit()
+            # The loop is stopped, but we execute it one more time to call `a_quit` which
+            # will call any cleaning method including async ones.
+            asyncio.get_event_loop().run_until_complete(self.a_quit())
 
     @classmethod
     def run(cls):
@@ -800,6 +802,22 @@
         if raise_exc:
             raise QuitException
 
+    async def a_quit(self, exit_code=0, raise_exc=True):
+        """Execute async quit callback before actually quitting
+
+        This method should be prefered to ``quit``, as it executes async quit callbacks
+        which may be necessary for proper cleaning of session.
+        """
+        try:
+            callbacks_list = self._on_quit_callbacks
+        except AttributeError:
+            pass
+        else:
+            for callback, args, kwargs in callbacks_list:
+                await aio.maybe_async(callback(*args, **kwargs))
+            callbacks_list.clear()
+        self.quit(exit_code, raise_exc)
+
     async def check_jids(self, jids):
         """Check jids validity, transform roster name to corresponding jids