diff --git a/lib/tfw/networking/async_solvable_connector.py b/lib/tfw/networking/async_solvable_connector.py new file mode 100644 index 0000000..be12938 --- /dev/null +++ b/lib/tfw/networking/async_solvable_connector.py @@ -0,0 +1,14 @@ +from tfw.networking.serialization import deserialize_all +from tfw.networking.solvable_connector import SolvableConnector + + +class AsyncSolvableConnector(SolvableConnector): + def __init__(self, async_zmq_context=None): + if async_zmq_context is None: + from zmq.eventloop.future import Context + async_zmq_context = Context.instance() + super(AsyncSolvableConnector, self).__init__(async_zmq_context) + + async def recv(self): + response = await self._zmq_req_socket.recv_multipart() + return deserialize_all(*response) diff --git a/lib/tfw/networking/server/controller_responder.py b/lib/tfw/networking/server/controller_responder.py new file mode 100644 index 0000000..32567d7 --- /dev/null +++ b/lib/tfw/networking/server/controller_responder.py @@ -0,0 +1,27 @@ +from tfw.networking.controller_connector import ControllerConnector +from tfw.networking.serialization import deserialize_all, serialize_all + + +class ControllerResponder: + def __init__(self, fsm): + self.fsm = fsm + self.controller_connector = ControllerConnector() + self.controller_connector.register_callback(self.handle_controller_request) + self.controller_request_handlers = { + 'solution_check': self.handle_solution_check_request, + 'test': self.handle_test_request + } + + def handle_controller_request(self, stream, msg_parts): + key, data = deserialize_all(*msg_parts) + response = self.controller_request_handlers[key](data) + stream.send_multipart(serialize_all(key, response)) + + def handle_test_request(self, data): + return 'OK' + + def handle_solution_check_request(self, data): + return { + 'solved': self.fsm.is_solved(), + 'message': 'solved' if self.fsm.is_solved() else 'not solved' + } diff --git a/lib/tfw/networking/server/tfw_server.py b/lib/tfw/networking/server/tfw_server.py index fbd5ec3..0129686 100644 --- a/lib/tfw/networking/server/tfw_server.py +++ b/lib/tfw/networking/server/tfw_server.py @@ -1,7 +1,6 @@ from tornado.web import Application -from tfw.networking.controller_connector import ControllerConnector -from tfw.networking.serialization import deserialize_all, serialize_all +from tfw.networking.server.controller_responder import ControllerResponder from tfw.networking.server.zmq_websocket_handler import FSMManagingSocketHandler @@ -9,25 +8,13 @@ class TFWServer: def __init__(self, fsm_type): self._fsm = fsm_type() self.application = Application( - [(r'/ws', FSMManagingSocketHandler, {'fsm': self.fsm})], - autoreload=True + [(r'/ws', FSMManagingSocketHandler, {'fsm': self.fsm})] ) - self.controller_connector = ControllerConnector() - self.controller_connector.register_callback(self.zmq_callback) + self.controller_responder = ControllerResponder(self.fsm) @property def fsm(self): return self._fsm - def zmq_callback(self, stream, msg_parts): - key, data = deserialize_all(*msg_parts) - if key == 'test': - stream.send_multipart(serialize_all(key, 'OK')) - if key == 'solution_check': - stream.send_multipart(serialize_all(key, { - 'solved': self.fsm.is_solved(), - 'message': 'solved' if self.fsm.is_solved() else 'not solved' - })) - def listen(self, port): self.application.listen(port) diff --git a/src/controller/app.py b/src/controller/app.py index c304231..67b2faa 100644 --- a/src/controller/app.py +++ b/src/controller/app.py @@ -4,13 +4,13 @@ from tornado.web import Application from tao.config import taoenv from tfw.config import tfwenv from handlers import SolutionCheckHandler, TestHandler -from tfw.networking.solvable_connector import SolvableConnector +from tfw.networking.async_solvable_connector import AsyncSolvableConnector from tfw.config.logs import logging log = logging.getLogger(__name__) if __name__ == '__main__': - solvable_connector = SolvableConnector() + solvable_connector = AsyncSolvableConnector() routes = [ (r'/{secret}/?'.format(secret=taoenv.SECRET), SolutionCheckHandler, {'solvable_connector': solvable_connector}), (r'/{secret}/test/?'.format(secret=taoenv.SECRET), TestHandler, {'solvable_connector': solvable_connector}) diff --git a/src/controller/handlers/solution_check_handler.py b/src/controller/handlers/solution_check_handler.py index 5a79feb..cfe2c1c 100644 --- a/src/controller/handlers/solution_check_handler.py +++ b/src/controller/handlers/solution_check_handler.py @@ -7,9 +7,9 @@ class SolutionCheckHandler(RequestHandler): def initialize(self, solvable_connector): self.solvable_connector = solvable_connector - def get(self): + async def get(self): log.debug('Sending request to solvable') self.solvable_connector.send('solution_check', {}) - resp_key, resp_data = self.solvable_connector.recv() + resp_key, resp_data = await self.solvable_connector.recv() log.debug('Received answer from solvable') self.write(resp_data) diff --git a/src/controller/handlers/test_handler.py b/src/controller/handlers/test_handler.py index bc4d690..564bcdc 100644 --- a/src/controller/handlers/test_handler.py +++ b/src/controller/handlers/test_handler.py @@ -5,7 +5,7 @@ class TestHandler(RequestHandler): def initialize(self, solvable_connector): self.solvable_connector = solvable_connector - def get(self): + async def get(self): self.solvable_connector.send('test', {}) - resp_key, resp_data = self.solvable_connector.recv() + resp_key, resp_data = await self.solvable_connector.recv() self.write(resp_data)