from typing import Coroutine, Generator, Iterator, List, Tuple from queue import PriorityQueue from time import time, sleep Task = Coroutine[ object, object, object ] class Sched: def add( self, task: Task ) -> None: self.tasks.append( task.__await__() ) def __init__( self ) -> None: self.tasks : List[ Iterator[ int ] ] = [] self.queue : PriorityQueue[ Tuple[ float, int ] ] self.queue = PriorityQueue() class suspend: def __init__( self, n: int ) -> None: self.msec = n def __await__( self ) -> Generator[ int, None, None ]: yield self.msec def schedule( self, i: int ) -> None: try: task = self.tasks[ i ] delay = next( task ) item = ( time() + delay / 1000, i ) self.queue.put( item ) except StopIteration: pass def run( self ) -> None: for i in range( len( self.tasks ) ): self.schedule( i ) while not self.queue.empty(): when, what = self.queue.get() pause = when - time() if pause > 0: sleep( pause ) self.schedule( what ) import run_tests