From 1eec3d3078d5ba2cb5e3432e1e1275eaa144b6d4 Mon Sep 17 00:00:00 2001 From: nocturn9x Date: Sun, 5 Apr 2020 10:10:52 +0000 Subject: [PATCH] Various fixes, check experiment.py file --- experiment.py | 26 ++++++++++++++++++++------ giambio/traps.py | 1 - giambio/util.py | 15 +++++++++------ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/experiment.py b/experiment.py index 0d6fb99..4fedf0a 100644 --- a/experiment.py +++ b/experiment.py @@ -4,18 +4,26 @@ loop = giambio.EventLoop() """ -What works and what does not (25th March 2020 20:35) +What works and what does not (5 Apr 2020 12:06 AM): - Run tasks concurrently: V - Join mechanism: V - Sleep mechanism: V - Cancellation mechanism: V -- Exception propagation: X +- Exception propagation: X Note: Almost ready - Concurrent I/O: V - Return values of coroutines: V - Scheduling tasks for future execution: V - Task Spawner (context manager): V + +What's left to implement: + +- An event system to wake up tasks programmatically +- Lower-level primitives such as locks, queues, semaphores +- File I/O (Also, consider that Windows won't allow select to work on non-socket fds) +- Complete the AsyncSocket implementation (happy eyeballs, other methods) +- Debugging tools """ async def countdown(n): @@ -43,16 +51,22 @@ 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: print("Spawning countdown immediately, scheduling count for 4 secs from now") async with giambio.TaskManager(loop) as manager: task = manager.spawn(countdown(8)) - manager.schedule(count(8, 2), 4) + task2 = manager.schedule(count(8, 2), 4) + 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 -loop.start(main) - +try: + loop.start(main) +except Exception: # Exceptions climb the whole stack + print("Exceptions propagate!") diff --git a/giambio/traps.py b/giambio/traps.py index 2ccdf76..bcd208f 100644 --- a/giambio/traps.py +++ b/giambio/traps.py @@ -74,4 +74,3 @@ def _cancel(task): task.cancelled = True yield "want_cancel", task - diff --git a/giambio/util.py b/giambio/util.py index 33d96ec..6f661b5 100644 --- a/giambio/util.py +++ b/giambio/util.py @@ -17,10 +17,14 @@ class TaskManager: async def _cancel_and_raise(self, exc): - self.loop._exiting = True # Tells the loop not to catch all exceptions - for task in self.tasks: - await task.cancel() - raise 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 + raise exc async def __aenter__(self): return self @@ -30,8 +34,7 @@ class TaskManager: task = self.tasks.popleft() self.values[task] = await task.join() if task.result.exc: - if task.result.exc != CancelledError: - await self._cancel_and_raise(task.result.exc) + await self._cancel_and_raise(task.result.exc) def spawn(self, coroutine: types.coroutine): """Schedules a task for execution, appending it to the call stack"""