diff --git a/experiment.py b/experiment.py index 4fedf0a..f913b23 100644 --- a/experiment.py +++ b/experiment.py @@ -4,13 +4,13 @@ loop = giambio.EventLoop() """ -What works and what does not (5 Apr 2020 12:06 AM): +What works and what does not (5 Apr 2020 13:35) - Run tasks concurrently: V - Join mechanism: V - Sleep mechanism: V - Cancellation mechanism: V -- Exception propagation: X Note: Almost ready +- Exception propagation: V - Concurrent I/O: V - Return values of coroutines: V - Scheduling tasks for future execution: V @@ -26,6 +26,7 @@ What's left to implement: - Debugging tools """ + async def countdown(n): try: while n > 0: @@ -38,7 +39,7 @@ async def countdown(n): return "Count DOWN over" except giambio.CancelledError: print("countdown cancelled!") - raise Exception("Oh no!") # TODO Propagate this +# raise Exception("Oh no!") # This will propagate async def count(stop, step=1): try: @@ -51,7 +52,7 @@ async def count(stop, step=1): return "Count UP over" except giambio.CancelledError: print("count cancelled!") -# raise BaseException # This will propagate + async def main(): try: @@ -59,11 +60,12 @@ async def main(): async with giambio.TaskManager(loop) as manager: task = manager.spawn(countdown(8)) task2 = manager.schedule(count(8, 2), 4) - await task.cancel() # This works, but other tasks continue running +# await giambio.sleep(3) +# await task.cancel() # This works, but other tasks continue running for task, ret in manager.values.items(): print(f"Function '{task.coroutine.__name__}' at {hex(id(task.coroutine))} returned an object of type '{type(ret).__name__}': {repr(ret)}") except Exception as e: - print(f"Actually I prefer to catch it here: {e}") # Everything works just as expected, the try/except block below won't trigger + print(f"Actually I prefer to catch it here: {repr(e)}") # Everything works just as expected, the try/except block below won't trigger try: diff --git a/giambio/core.py b/giambio/core.py index bce54f8..3150e2e 100644 --- a/giambio/core.py +++ b/giambio/core.py @@ -147,8 +147,10 @@ class EventLoop: def want_cancel(self, task): self.to_run.extend(self.joined.pop(self.running, ())) self.to_run.append(self.running) # Reschedules the parent task - task.throw(CancelledError()) - + try: + task.throw(CancelledError()) + except Exception as e: + task.result.exc = e async def connect_sock(self, sock: socket.socket, addr: tuple): try: # "Borrowed" from curio diff --git a/giambio/util.py b/giambio/util.py index 6f661b5..03c1ee0 100644 --- a/giambio/util.py +++ b/giambio/util.py @@ -19,11 +19,8 @@ class TaskManager: async def _cancel_and_raise(self, exc): if not isinstance(exc, CancelledError): self.loop._exiting = True # Tells the loop not to catch all exceptions - try: - for task in self.tasks: - await task.cancel() - except Exception: - pass + for task in self.tasks: + await task.cancel() raise exc async def __aenter__(self):