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:
self.current_task.exc = error
self.reschedule_parent(self.current_task)
raise # Maybe find a better way to propagate errors?
if self.selector.get_map():
try:
self.check_io()
except BaseException as error:
self.current_task.exc = error
self.reschedule_parent(self.current_task)
raise # Maybe find a better way to propagate errors?
while self.tasks: # While there are tasks to run
self.current_task = self.tasks.popleft() # Sets the currently running task
try:
@ -97,7 +95,6 @@ class AsyncScheduler:
except BaseException as error: # Coroutine raised
self.current_task.exc = error
self.reschedule_parent(self.current_task)
raise # Maybe find a better way to propagate errors?
def check_events(self):
"""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
parent task"""
if child not in self.joined:
self.joined[child] = self.current_task
if child.cancelled: # Task was cancelled and is therefore dead
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:
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):
"""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.
"""
"""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 socket
@ -47,7 +50,8 @@ def join(task):
:type task: class: Task
"""
yield "join", task
res = yield "join", task
return task.result
@types.coroutine
@ -89,12 +93,19 @@ def want_write(sock: socket.socket):
@types.coroutine
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
@types.coroutine
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
return msg

View File

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