# run_async.py # # Copyright 2022 brombinmirko # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, in version 3 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import sys import threading import traceback import logging from gi.repository import GLib logger = logging.getLogger("FirstSetup::Async") class RunAsync(threading.Thread): """ This class is used to execute a function asynchronously. It takes a function, a callback and a list of arguments as input. """ def __init__(self, task_func, callback=None, *args, **kwargs): if "DEBUG_MODE" in os.environ: import faulthandler faulthandler.enable() self.source_id = None assert threading.current_thread() is threading.main_thread() super(RunAsync, self).__init__( target=self.__target, args=args, kwargs=kwargs) self.task_func = task_func self.callback = callback if callback else lambda r, e: None self.daemon = kwargs.pop("daemon", True) self.start() def __target(self, *args, **kwargs): result = None error = None logger.debug(f"Running async job [{self.task_func}].") try: result = self.task_func(*args, **kwargs) except Exception as exception: logger.error("Error while running async job: " f"{self.task_func}\nException: {exception}") error = exception _ex_type, _ex_value, trace = sys.exc_info() traceback.print_tb(trace) traceback_info = '\n'.join(traceback.format_tb(trace)) self.source_id = GLib.idle_add(self.callback, result, error) return self.source_id