request_handler.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import sys
  2. import modelverse_kernel.primitives as primitive_functions
  3. import modelverse_kernel.jit as jit
  4. from collections import defaultdict
  5. class RequestHandler(object):
  6. def __init__(self):
  7. self.generator_stack = []
  8. self.handlers = {"CALL": self.execute_call,
  9. "CALL_ARGS": self.execute_call_args,
  10. "CALL_KWARGS": self.execute_call_kwargs,
  11. "SLEEP": self.execute_sleep}
  12. def push_generator(self, gen):
  13. self.generator_stack.append(gen)
  14. def handle_request(self, reply):
  15. while self.generator_stack:
  16. try:
  17. gen = self.generator_stack[-1]
  18. requests = gen.send(reply)
  19. # Generated new request, so process
  20. if requests and requests[0][0] in self.handlers:
  21. # Known request, so process that one
  22. if len(requests) > 1:
  23. raise Exception("CALL_* and SLEEP operations MUST be split in individual yields")
  24. # Try to add a new generator to branch into
  25. reply = None
  26. self.generator_stack.append(None)
  27. # This next command potentially raises a finished message already, meaning that we should stop already
  28. # We avoid an extra try/except block by putting the None on the stack already
  29. self.generator_stack[-1] = self.handlers[requests[0][0]](requests[0][1])
  30. else:
  31. # MvS request, so forward that instead
  32. return requests
  33. except StopIteration:
  34. # Exception, so finished execution of this generator, passing on None to the caller
  35. del self.generator_stack[-1]
  36. reply = [None]
  37. except primitive_functions.PrimitiveFinished as ex:
  38. # Exception, so finished execution of this generator, passing on ex.result to the caller
  39. del self.generator_stack[-1]
  40. reply = [ex.result]
  41. except primitive_functions.SleepKernel:
  42. # Processing sleep, so pop its generator and reraise
  43. del self.generator_stack[-1]
  44. raise
  45. def execute_call(self, request_args):
  46. return request_args[0]
  47. def execute_call_kwargs(self, request_args):
  48. return request_args[0](**(request_args[1]))
  49. def execute_call_args(self, request_args):
  50. return request_args[0](*(request_args[1]))
  51. def execute_sleep(self, request_args):
  52. raise primitive_functions.SleepKernel(request_args[0], request_args[1])