from typing import Coroutine, Generator, Iterator, List, Tuple from queue import PriorityQueue from time import time, sleep Task = Coroutine[ object, object, object ] class IOPlex: def __init__( self, factory ) -> None: self.tasks = {} self.factory = factory self.reply = None self.counter = 0 class read: def __await__( self ): x = yield (); return x 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 write( self, data ): self.reply = data def connect( self ): ident = self.counter self.counter += 1 self.tasks[ ident ] = \ self.factory( self.read, self.write ).__await__() next( self.tasks[ ident ] ) return ident def close( self, ident ): del self.tasks[ ident ] def send( self, ident, data ): if ident not in self.tasks: return None try: self.tasks[ ident ].send( data ) except StopIteration: return None r, self.reply = self.reply, None return r