diff --git a/src/backend/qml_bridge.py b/src/backend/qml_bridge.py index 848bf728..c3f94f5e 100644 --- a/src/backend/qml_bridge.py +++ b/src/backend/qml_bridge.py @@ -21,7 +21,7 @@ import traceback from concurrent.futures import Future from operator import attrgetter from threading import Thread -from typing import Coroutine, Dict, Sequence +from typing import Coroutine, Dict, Sequence, Set import pyotherside @@ -53,6 +53,7 @@ class QMLBridge: self.backend: Backend = Backend() self._running_futures: Dict[str, Future] = {} + self._cancelled_early: Set[str] = set() Thread(target=self._start_asyncio_loop).start() @@ -78,6 +79,10 @@ class QMLBridge: def _call_coro(self, coro: Coroutine, uuid: str) -> None: """Schedule a coroutine to run in our thread and return a `Future`.""" + if uuid in self._cancelled_early: + self._cancelled_early.remove(uuid) + return + def on_done(future: Future) -> None: """Send a PyOtherSide event with the coro's result/exception.""" result = exception = trace = None @@ -101,7 +106,10 @@ class QMLBridge: ) -> None: """Schedule a coroutine from the `QMLBridge.backend` object.""" - self._call_coro(attrgetter(name)(self.backend)(*args), uuid) + if uuid in self._cancelled_early: + self._cancelled_early.remove(uuid) + else: + self._call_coro(attrgetter(name)(self.backend)(*args), uuid) def call_client_coro( @@ -109,17 +117,20 @@ class QMLBridge: ) -> None: """Schedule a coroutine from a `QMLBridge.backend.clients` client.""" - client = self.backend.clients[user_id] - self._call_coro(attrgetter(name)(client)(*args), uuid) + if uuid in self._cancelled_early: + self._cancelled_early.remove(uuid) + else: + client = self.backend.clients[user_id] + self._call_coro(attrgetter(name)(client)(*args), uuid) def cancel_coro(self, uuid: str) -> None: """Cancel a couroutine scheduled by the `QMLBridge` methods.""" - try: + if uuid in self._running_futures: self._running_futures[uuid].cancel() - except KeyError: - log.warning("Couldn't cancel coroutine %s, future not found", uuid) + else: + self._cancelled_early.add(uuid) def pdb(self, additional_data: Sequence = ()) -> None: diff --git a/src/gui/PythonBridge/EventHandlers.qml b/src/gui/PythonBridge/EventHandlers.qml index 96850f79..2349836b 100644 --- a/src/gui/PythonBridge/EventHandlers.qml +++ b/src/gui/PythonBridge/EventHandlers.qml @@ -35,6 +35,8 @@ QtObject { } function onCoroutineDone(uuid, result, error, traceback) { + if (! Globals.pendingCoroutines[uuid]) return + const onSuccess = Globals.pendingCoroutines[uuid].onSuccess const onError = Globals.pendingCoroutines[uuid].onError diff --git a/src/gui/PythonBridge/PythonBridge.qml b/src/gui/PythonBridge/PythonBridge.qml index 029fe8a3..99a9e3e1 100644 --- a/src/gui/PythonBridge/PythonBridge.qml +++ b/src/gui/PythonBridge/PythonBridge.qml @@ -43,6 +43,7 @@ Python { } function cancelCoro(uuid) { + delete Globals.pendingCoroutines[uuid] call("BRIDGE.cancel_coro", [uuid]) }