316 lines
8.5 KiB
Python
316 lines
8.5 KiB
Python
from abc import ABC, abstractmethod
|
|
from aiosched.task import Task
|
|
from aiosched.context import TaskContext
|
|
from selectors import EVENT_READ, EVENT_WRITE
|
|
|
|
|
|
class BaseDebugger(ABC):
|
|
"""
|
|
The base for all debugger objects
|
|
"""
|
|
|
|
@abstractmethod
|
|
def on_start(self):
|
|
"""
|
|
This method is called when the event
|
|
loop starts executing
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_exit(self):
|
|
"""
|
|
This method is called when the event
|
|
loop exits entirely (all tasks completed)
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_task_schedule(self, task: Task, delay: float):
|
|
"""
|
|
This method is called when a new task is
|
|
scheduled (not spawned)
|
|
|
|
:param task: The Task object representing a
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
:param delay: The delay, in seconds, after which
|
|
the task will start executing
|
|
:type delay: float
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_task_spawn(self, task: Task):
|
|
"""
|
|
This method is called when a new task is
|
|
spawned
|
|
|
|
:param task: The Task object representing a
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_task_exit(self, task: Task):
|
|
"""
|
|
This method is called when a task exits
|
|
|
|
:param task: The Task object representing an
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def before_task_step(self, task: Task):
|
|
"""
|
|
This method is called right before
|
|
calling a task's run() method
|
|
|
|
:param task: The Task object representing an
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def after_task_step(self, task: Task):
|
|
"""
|
|
This method is called right after
|
|
calling a task's run() method
|
|
|
|
:param task: The Task object representing an
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def before_sleep(self, task: Task, seconds: float):
|
|
"""
|
|
This method is called before a task goes
|
|
to sleep
|
|
|
|
:param task: The Task object representing an
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
:param seconds: The amount of seconds the
|
|
task wants to sleep
|
|
:type seconds: int
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def after_sleep(self, task: Task, seconds: float):
|
|
"""
|
|
This method is called after a tasks
|
|
awakes from sleeping
|
|
|
|
:param task: The Task object representing an
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
:param seconds: The amount of seconds the
|
|
task actually slept
|
|
:type seconds: float
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def before_io(self, timeout: float):
|
|
"""
|
|
This method is called right before
|
|
the event loop checks for I/O events
|
|
|
|
:param timeout: The max. amount of seconds
|
|
that the loop will hang when using the select()
|
|
system call
|
|
:type timeout: float
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def after_io(self, timeout: float):
|
|
"""
|
|
This method is called right after
|
|
the event loop has checked for I/O events
|
|
|
|
:param timeout: The actual amount of seconds
|
|
that the loop has hung when using the select()
|
|
system call
|
|
:type timeout: float
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def before_cancel(self, task: Task):
|
|
"""
|
|
This method is called right before a task
|
|
gets cancelled
|
|
|
|
:param task: The Task object representing a
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def after_cancel(self, task: Task) -> object:
|
|
"""
|
|
This method is called right after a task
|
|
gets cancelled
|
|
|
|
:param task: The Task object representing a
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_exception_raised(self, task: Task, exc: BaseException):
|
|
"""
|
|
This method is called right after a task
|
|
has raised an exception
|
|
|
|
:param task: The Task object representing a
|
|
aiosched Task and wrapping a coroutine
|
|
:type task: :class: aiosched.task.Task
|
|
:param exc: The exception that was raised
|
|
:type exc: BaseException
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_context_creation(self, ctx: TaskContext):
|
|
"""
|
|
This method is called right after a task
|
|
context is initialized, i.e. when set_context
|
|
in the event loop is called
|
|
|
|
:param ctx: The context object
|
|
:type ctx: TaskContext
|
|
:return:
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_context_exit(self, ctx: TaskContext):
|
|
"""
|
|
This method is called right before a task
|
|
context is closed, i.e. when close_context
|
|
in the event loop is called
|
|
|
|
:param ctx: The context object
|
|
:type ctx: TaskContext
|
|
:return:
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_io_schedule(self, stream, event: int):
|
|
"""
|
|
This method is called whenever the
|
|
perform_io primitive is called within
|
|
the aiosched event loop with the stream
|
|
to be registered in the selector and the
|
|
chosen event mask
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
@abstractmethod
|
|
def on_io_unschedule(self, stream):
|
|
"""
|
|
This method is called whenever a stream
|
|
is unregistered from the loop's I/O selector
|
|
"""
|
|
|
|
return NotImplemented
|
|
|
|
|
|
class SimpleDebugger(BaseDebugger):
|
|
"""
|
|
A simple debugger for aiosched
|
|
"""
|
|
|
|
def on_start(self):
|
|
print("## Started running")
|
|
|
|
def on_exit(self):
|
|
print("## Finished running")
|
|
|
|
def on_task_schedule(self, task, delay: int):
|
|
print(
|
|
f">> A task named '{task.name}' was scheduled to run in {delay:.2f} seconds"
|
|
)
|
|
|
|
def on_task_spawn(self, task):
|
|
print(f">> A task named '{task.name}' was spawned")
|
|
|
|
def on_task_exit(self, task):
|
|
print(f"<< Task '{task.name}' exited")
|
|
|
|
def before_task_step(self, task):
|
|
print(f"-> About to run a step for '{task.name}'")
|
|
|
|
def after_task_step(self, task):
|
|
print(f"<- Ran a step for '{task.name}'")
|
|
|
|
def before_sleep(self, task, seconds):
|
|
print(f"# About to put '{task.name}' to sleep for {seconds:.2f} seconds")
|
|
|
|
def after_sleep(self, task, seconds):
|
|
print(f"# Task '{task.name}' slept for {seconds:.2f} seconds")
|
|
|
|
def before_io(self, timeout):
|
|
if timeout is None:
|
|
timeout = float("inf")
|
|
print(f"!! About to check for I/O for up to {timeout:.2f} seconds")
|
|
|
|
def after_io(self, timeout):
|
|
print(f"!! Done I/O check (waited for {timeout:.2f} seconds)")
|
|
|
|
def before_cancel(self, task):
|
|
print(f"// About to cancel '{task.name}'")
|
|
|
|
def after_cancel(self, task):
|
|
print(f"// Cancelled '{task.name}'")
|
|
|
|
def on_exception_raised(self, task, exc):
|
|
print(f"== '{task.name}' raised {repr(exc)}")
|
|
|
|
def on_context_creation(self, ctx):
|
|
print(f"=> A new context was created by {ctx.entry_point.name!r}")
|
|
|
|
def on_context_exit(self, ctx):
|
|
print(f"=> A context was closed by {ctx.entry_point.name}")
|
|
|
|
def on_io_schedule(self, stream, event: int):
|
|
evt = ""
|
|
if event == EVENT_READ:
|
|
evt = "reading"
|
|
elif event == EVENT_WRITE:
|
|
evt = "writing"
|
|
elif event == EVENT_WRITE | EVENT_READ:
|
|
evt = "reading or writing"
|
|
print(f"|| Stream {stream!r} was scheduled for {evt}")
|
|
|
|
def on_io_unschedule(self, stream):
|
|
print(f"|| Stream {stream!r} was unscheduled") |