Mercurial > libervia-backend
diff sat_frontends/jp/base.py @ 3043:3df611adb598
jp: handle dbus bridge with asyncio:
D-Bus bridge is now working again, using the new AsyncIO version. To make it work, the
GLib loop is run in a separated thread.
Loops have been moved to the `loops` module.
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 01 Oct 2019 22:49:10 +0200 |
parents | fee60f17ebac |
children | d9f328374473 |
line wrap: on
line diff
--- a/sat_frontends/jp/base.py Tue Oct 01 22:49:10 2019 +0200 +++ b/sat_frontends/jp/base.py Tue Oct 01 22:49:10 2019 +0200 @@ -1,5 +1,4 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- +#!/usr/bin/env python3 # jp: a SAT command line tool # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) @@ -41,6 +40,7 @@ from sat.tools.common import date_utils from sat.core import exceptions import sat_frontends.jp +from sat_frontends.jp.loops import QuitException, getJPLoop from sat_frontends.jp.constants import Const as C from sat_frontends.tools import misc import xml.etree.ElementTree as ET # FIXME: used temporarily to manage XMLUI @@ -50,109 +50,8 @@ # we get bridge name from conf and initialise the right class accordingly main_config = config.parseMainConf() bridge_name = config.getConfig(main_config, '', 'bridge', 'dbus') -USER_INTER_MSG = _("User interruption: good bye") - - -class QuitException(BaseException): - """Quitting is requested - - This is used to stop execution when host.quit() is called - """ - - -# TODO: move loops handling in a separated module -if 'dbus' in bridge_name: - from gi.repository import GLib - - - class JPLoop(object): - - def __init__(self): - self.loop = GLib.MainLoop() - - def run(self): - self.loop.run() - - def quit(self, exit_code): - self.loop.quit() - sys.exit(exit_code) - - def call_later(self, delay, callback, *args): - """call a callback repeatedly - - @param delay(int): delay between calls in ms - @param callback(callable): method to call - if the callback return True, the call will continue - else the calls will stop - @param *args: args of the callbac - """ - GLib.timeout_add(delay, callback, *args) - -else: - import signal - from twisted.internet import asyncioreactor - asyncioreactor.install() - from twisted.internet import reactor, defer - - class JPLoop(object): - - def __init__(self): - # exit code must be set when using quit, so if it's not set - # something got wrong and we must report it - self._exit_code = C.EXIT_INTERNAL_ERROR +JPLoop = getJPLoop(bridge_name) - def run(self, jp, *args): - self.jp = jp - signal.signal(signal.SIGINT, self._on_sigint) - defer.ensureDeferred(self._start(jp, *args)) - try: - reactor.run(installSignalHandlers=False) - except SystemExit as e: - self._exit_code = e.code - sys.exit(self._exit_code) - - async def _start(self, jp, *args): - fut = asyncio.ensure_future(jp.main(*args)) - try: - await defer.Deferred.fromFuture(fut) - except BaseException: - import traceback - traceback.print_exc() - jp.quit(1) - - def quit(self, exit_code): - self._exit_code = exit_code - reactor.stop() - - def _timeout_cb(self, args, callback, delay): - try: - ret = callback(*args) - # FIXME: temporary hack to avoid traceback when using XMLUI - # to be removed once create_task is not used anymore in - # xmlui_manager (i.e. once sat_frontends.tools.xmlui fully supports - # async syntax) - except QuitException: - return - if ret: - reactor.callLater(delay, self._timeout_cb, args, callback, delay) - - def call_later(self, delay, callback, *args): - delay = float(delay) / 1000 - reactor.callLater(delay, self._timeout_cb, args, callback, delay) - - def _on_sigint(self, sig_number, stack_frame): - """Called on keyboard interruption - - Print user interruption message, set exit code and stop reactor - """ - print("\r" + USER_INTER_MSG) - self._exit_code = C.EXIT_USER_CANCELLED - reactor.callFromThread(reactor.stop) - - -if bridge_name == "embedded": - from sat.core import sat_main - sat = sat_main.SAT() try: import progressbar