Fixed cancellation and added a few docstrings

This commit is contained in:
nocturn9x 2020-07-11 15:09:31 +00:00
parent d2a20a14fc
commit 84f8ac5728
3 changed files with 30 additions and 12 deletions

View File

@ -68,14 +68,12 @@ class AsyncScheduler:
except BaseException as error: except BaseException as error:
self.current_task.exc = error self.current_task.exc = error
self.reschedule_parent(self.current_task) self.reschedule_parent(self.current_task)
raise # Maybe find a better way to propagate errors?
if self.selector.get_map(): if self.selector.get_map():
try: try:
self.check_io() self.check_io()
except BaseException as error: except BaseException as error:
self.current_task.exc = error self.current_task.exc = error
self.reschedule_parent(self.current_task) self.reschedule_parent(self.current_task)
raise # Maybe find a better way to propagate errors?
while self.tasks: # While there are tasks to run while self.tasks: # While there are tasks to run
self.current_task = self.tasks.popleft() # Sets the currently running task self.current_task = self.tasks.popleft() # Sets the currently running task
try: try:
@ -97,7 +95,6 @@ class AsyncScheduler:
except BaseException as error: # Coroutine raised except BaseException as error: # Coroutine raised
self.current_task.exc = error self.current_task.exc = error
self.reschedule_parent(self.current_task) self.reschedule_parent(self.current_task)
raise # Maybe find a better way to propagate errors?
def check_events(self): def check_events(self):
"""Checks for ready or expired events and triggers them""" """Checks for ready or expired events and triggers them"""
@ -206,10 +203,18 @@ class AsyncScheduler:
coroutine returns or, if an exception gets raised, the exception will get propagated inside the coroutine returns or, if an exception gets raised, the exception will get propagated inside the
parent task""" parent task"""
if child not in self.joined: if child.cancelled: # Task was cancelled and is therefore dead
self.joined[child] = self.current_task self.tasks.append(self.current_task)
elif child.exc: # Task raised an error, propagate it!
self.reschedule_parent(child)
raise child.exc
elif child.finished:
self.tasks.append(self.current_task) # Task has already finished
else: else:
raise AlreadyJoinedError("Joining the same task multiple times is not allowed!") if child not in self.joined:
self.joined[child] = self.current_task
else:
raise AlreadyJoinedError("Joining the same task multiple times is not allowed!")
def sleep(self, seconds: int or float): def sleep(self, seconds: int or float):
"""Puts the caller to sleep for a given amount of seconds""" """Puts the caller to sleep for a given amount of seconds"""

View File

@ -14,7 +14,10 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
""" """
"""Helper methods to interact with the event loop""" # Helper methods to interact with the event loop
# These coroutines are the one and only way to interact
# with the event loop from the user's perspective, and
# the entire library is based on these traps
import types import types
import socket import socket
@ -47,7 +50,8 @@ def join(task):
:type task: class: Task :type task: class: Task
""" """
yield "join", task res = yield "join", task
return task.result
@types.coroutine @types.coroutine
@ -89,12 +93,19 @@ def want_write(sock: socket.socket):
@types.coroutine @types.coroutine
def event_set(event, value): def event_set(event, value):
"""Communicates to the loop that the given event object
must be set. This is important as the loop constantly
checks for active events to deliver them
"""
yield "event_set", event, value yield "event_set", event, value
@types.coroutine @types.coroutine
def event_wait(event): def event_wait(event):
"""Notifies the event loop that the current task has to wait
for the event to trigger
"""
msg = yield "event_wait", event msg = yield "event_wait", event
return msg return msg

View File

@ -7,7 +7,7 @@ async def countdown(n: int):
n -= 1 n -= 1
await giambio.sleep(1) await giambio.sleep(1)
print("Countdown over") print("Countdown over")
return 0
async def countup(stop: int, step: int = 1): async def countup(stop: int, step: int = 1):
x = 0 x = 0
@ -16,6 +16,7 @@ async def countup(stop: int, step: int = 1):
x += 1 x += 1
await giambio.sleep(step) await giambio.sleep(step)
print("Countup over") print("Countup over")
return 1
async def main(): async def main():
@ -24,10 +25,11 @@ async def main():
print("Counters started, awaiting completion") print("Counters started, awaiting completion")
await giambio.sleep(2) await giambio.sleep(2)
print("Slept 2 seconds, killing countup") print("Slept 2 seconds, killing countup")
await cup.cancel() ## DOES NOT WORK!!! await cup.cancel()
print("Countup cancelled") print("Countup cancelled")
await cup.join() up = await cup.join()
await cdown.join() down = await cdown.join()
print(f"Countup returned: {up}\nCountdown returned: {down}")
print("Task execution complete") print("Task execution complete")
if __name__ == "__main__": if __name__ == "__main__":