# # Copyright (C) 2018 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties 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, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # from abc import ABC, abstractmethod from pyanaconda.core.signal import Signal from pyanaconda.core.async_utils import async_action_nowait __all__ = ['Runnable'] class Runnable(ABC): """Abstract class that allows to run a task.""" def __init__(self): super().__init__() self._started_signal = Signal() self._stopped_signal = Signal() self._failed_signal = Signal() self._succeeded_signal = Signal() @property def started_signal(self): """Signal emitted when the task starts.""" return self._started_signal @property def stopped_signal(self): """Signal emitted when the task stops.""" return self._stopped_signal @property def failed_signal(self): """Signal emitted when the task fails.""" return self._failed_signal @property def succeeded_signal(self): """Signal emitted when the task succeeds.""" return self._succeeded_signal @property @abstractmethod def is_running(self): """Is the task running.""" return False @abstractmethod def start(self): """Start the task run. Your task should run the following callbacks: self._task_started_callback self._task_run_callback self._task_failed_callback self._task_succeeded_callback self._task_stopped_callback Make sure that you call self._task_started_callback at the beginning of the task lifetime to inform that the task is running now. Run self._task_run_callback to do the actual job of the task. In a case of failure, call self._task_failed_callback to inform that the task has failed. You will still need to call also self._task_stopped_callback. In a case of success, call self._task_succeeded_callback to inform that the task has succeeded. Make sure that you always call self._task_stopped_callback at the end of the task lifetime to inform that the task is not running anymore. """ pass @async_action_nowait def _task_started_callback(self): """Callback for a started task.""" self._started_signal.emit() @abstractmethod def _task_run_callback(self): """Run the task.""" pass @async_action_nowait def _task_failed_callback(self): """Callback for a failed task.""" self._failed_signal.emit() @async_action_nowait def _task_succeeded_callback(self): """Callback for a successful task.""" self._succeeded_signal.emit() @async_action_nowait def _task_stopped_callback(self): """Callback for a terminated task.""" self._stopped_signal.emit() @abstractmethod def finish(self): """Finish the task run. This method should be called after the task was started and stopped. Re-raise any exception that was raised during the task run and wasn't propagated by the self.start method. """ pass