From e04cc08dd66eb71eb363d167eda57654c06495bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Bokros?= Date: Mon, 12 Feb 2018 11:09:28 +0100 Subject: [PATCH 1/4] Remove unnecessary autoreload As running the project outside a Docker container has become unfeasible, having this feature doesn't make sense anymore. --- lib/tfw/networking/server/tfw_server.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/tfw/networking/server/tfw_server.py b/lib/tfw/networking/server/tfw_server.py index fbd5ec3..c70e70b 100644 --- a/lib/tfw/networking/server/tfw_server.py +++ b/lib/tfw/networking/server/tfw_server.py @@ -9,8 +9,7 @@ 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) From 6f785b3ca722866779b915bda5226d103f6b86bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Bokros?= Date: Mon, 12 Feb 2018 11:28:35 +0100 Subject: [PATCH 2/4] Refactor solvable responses --- lib/tfw/networking/server/tfw_server.py | 26 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/tfw/networking/server/tfw_server.py b/lib/tfw/networking/server/tfw_server.py index c70e70b..b8972d7 100644 --- a/lib/tfw/networking/server/tfw_server.py +++ b/lib/tfw/networking/server/tfw_server.py @@ -12,21 +12,29 @@ class TFWServer: [(r'/ws', FSMManagingSocketHandler, {'fsm': self.fsm})] ) self.controller_connector = ControllerConnector() - self.controller_connector.register_callback(self.zmq_callback) + 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 + } @property def fsm(self): return self._fsm - def zmq_callback(self, stream, msg_parts): + def handle_controller_request(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' - })) + 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' + } def listen(self, port): self.application.listen(port) From 86aecd18a8b9df7924d828d2e3d427848fff40f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Bokros?= Date: Mon, 12 Feb 2018 13:22:55 +0100 Subject: [PATCH 3/4] Move responding-to-controller related stuff to its own class --- .../networking/server/controller_responder.py | 27 +++++++++++++++++++ lib/tfw/networking/server/tfw_server.py | 24 ++--------------- 2 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 lib/tfw/networking/server/controller_responder.py 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 b8972d7..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 @@ -11,30 +10,11 @@ class TFWServer: self.application = Application( [(r'/ws', FSMManagingSocketHandler, {'fsm': self.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 - } + self.controller_responder = ControllerResponder(self.fsm) @property def fsm(self): return self._fsm - 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' - } - def listen(self, port): self.application.listen(port) From cb46a8b80e5bab2adb01f4658de600489f4a1f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1lint=20Bokros?= Date: Mon, 12 Feb 2018 18:04:59 +0100 Subject: [PATCH 4/4] Make controller async --- lib/tfw/networking/async_solvable_connector.py | 14 ++++++++++++++ src/controller/app.py | 4 ++-- src/controller/handlers/solution_check_handler.py | 4 ++-- src/controller/handlers/test_handler.py | 4 ++-- 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 lib/tfw/networking/async_solvable_connector.py 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/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)