import sys import modelverse_kernel.primitives as primitive_functions import modelverse_kernel.jit as jit from collections import defaultdict class RequestHandler(object): def __init__(self): self.generator_stack = [] self.handlers = {"CALL": lambda i: i[0], "CALL_ARGS": lambda i: i[0](*(i[1])), "CALL_KWARGS": lambda i: i[0](**(i[1])), "SLEEP": self.execute_sleep} def push_generator(self, gen): self.generator_stack.append(gen) def handle_request(self, reply): while self.generator_stack: try: gen = self.generator_stack[-1] requests = gen.send(reply) # Generated new request, so process if requests and requests[0][0] in self.handlers: # Try to add a new generator to branch into reply = None self.generator_stack.append(None) # This next command potentially raises a finished message already, meaning that we should stop already # We avoid an extra try/except block by putting the None on the stack already self.generator_stack[-1] = self.handlers[requests[0][0]](requests[0][1]) else: # MvS request, so forward that instead return requests except StopIteration: # Exception, so finished execution of this generator, passing on None to the caller del self.generator_stack[-1] reply = [None] except primitive_functions.PrimitiveFinished as ex: # Exception, so finished execution of this generator, passing on ex.result to the caller del self.generator_stack[-1] reply = [ex.result] except primitive_functions.SleepKernel: # Processing sleep, so pop its generator and reraise del self.generator_stack[-1] raise def execute_sleep(self, request_args): raise primitive_functions.SleepKernel(request_args[0], request_args[1])