Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Simulate an asyncio based "web" server with a GameInstance that needs
- an input queue.
- GameInstance in this case is a class that takes input commands from a
- queue. Some commands are fast, and some are slow. The results of the commands
- are written to an output queue.
- """
- import asyncio
- import sys
- import time
- if sys.version_info < (3,5):
- assert False, "Bad python version %s" % sys.version_info
- else:
- print("Running python:", sys.version_info)
- Input_queue = asyncio.Queue()
- Output_queue = asyncio.Queue()
- DELAY = time.sleep
- async def queue_monitor():
- global Input_queue, Output_queue
- while True:
- await asyncio.sleep(5)
- ol = Output_queue.qsize()
- il = Input_queue.qsize()
- print("QM: Input queue: %d, Output queue: %d" % (il, ol))
- async def queue_eater():
- global Input_queue
- while True:
- inp = await Input_queue.get()
- print("EAT:", inp)
- class GameInstance:
- def __init__(self):
- self.vars = {}
- def get_var(self, name):
- if name not in 'abcd':
- raise ValueError("Variable name out of range: '%s'" % name)
- value = self.vars.get(name, 0)
- return value
- @staticmethod
- async def take_input():
- global Input_queue
- instr = await Input_queue.get()
- print("GI: Taking input: %s" % instr)
- return instr
- def op(self, op1, oper, op2):
- val1 = int(op1) if op1.isdigit() else self.get_var(op1)
- val2 = int(op2) if op2.isdigit() else self.get_var(op2)
- print("GI: Doing fast operation: %s %s %s" % (op1, oper, op2))
- result = {
- '+': (lambda a,b: a+b),
- '-': (lambda a,b: a-b),
- '*': (lambda a,b: a*b),
- '/': (lambda a,b: a//b),
- }[oper](val1, val2)
- print("GI: Result =", result)
- def opassign(self, op1, oper, op2):
- val1 = self.get_var(op1)
- val2 = int(op2) if op2.isdigit() else self.get_var(op2)
- print("GI: Starting slow operation: %s %s %s" % (op1, oper, op2))
- opfunc = {
- '=': (lambda a,b: b),
- '+=': (lambda a,b: a+b),
- '-=': (lambda a,b: a-b),
- '*=': (lambda a,b: a*b),
- '/=': (lambda a,b: a//b),
- }
- result = opfunc[oper](val1, val2)
- self.vars[op1] = result
- time.sleep(2)
- print("GI: Result =", result)
- def process_input(self, step):
- try:
- opd1, oper, opd2 = step.split()
- print("GI: process", (opd1, oper, opd2))
- if oper in ('=', '+=', '-=', '*=', '/='):
- self.opassign(opd1, oper, opd2)
- else:
- self.op(opd1, oper, opd2)
- except Exception as ex:
- print("GI: Input error. Could not parse: %s" % step)
- print("... exception:", ex)
- Input_queue.task_done()
- async def run(self):
- while True:
- # Give other coroutines a chance to run
- await asyncio.sleep(0)
- # block on queue
- step = await self.take_input()
- print("GI: run has input %s" % step)
- self.process_input(step)
- class WebsocketPool():
- """Get inputs, put them in input queue."""
- def __init__(self, loop):
- self.loop = loop
- loop.add_reader(sys.stdin, WebsocketPool.handle_input)
- print("WSP: Added reader for stdin")
- @staticmethod
- def handle_input():
- print("WSP: handle_input called")
- inp = sys.stdin.readline().strip()
- print("WSP: Got input: %s" % inp)
- asyncio.async(Input_queue.put(inp))
- print("WSP: Added to input queue")
- def main():
- game = GameInstance()
- loop = asyncio.get_event_loop()
- loop.set_debug(enabled=True)
- wsp = WebsocketPool(loop)
- print("MAIN: Created WebsocketPool")
- loop.create_task(queue_monitor())
- print("MAIN: Created queue_monitor task")
- #loop.create_task(queue_eater())
- loop.create_task(game.run())
- print("MAIN: Created game.run task")
- try:
- loop.run_forever()
- except KeyboardInterrupt:
- print("MAIN: Terminated from keyboard")
- finally:
- loop.close()
- if __name__ == '__main__':
- exit(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement