diff --git a/lib/tfw/networking/server/tfw_server.py b/lib/tfw/networking/server/tfw_server.py index 8411bd4..da1f49e 100644 --- a/lib/tfw/networking/server/tfw_server.py +++ b/lib/tfw/networking/server/tfw_server.py @@ -1,8 +1,10 @@ from tornado.web import Application +from collections import defaultdict from tfw.networking.server.controller_responder import ControllerResponder from tfw.networking.server.zmq_websocket_handler import ZMQWebSocketProxy from tfw.networking.event_handlers.server_connector import ServerUplinkConnector +from tfw.message_sender import MessageSender from tfw.config.logs import logging log = logging.getLogger(__name__) @@ -10,8 +12,9 @@ log = logging.getLogger(__name__) class TFWServer: def __init__(self, fsm_type): self._fsm = fsm_type() - self.fsm_updater = FSMUpdater(self._fsm) - self._fsm.subscribe(self.fsm_updater.update) + self._fsm_updater = FSMUpdater(self._fsm) + self._fsm_manager = FSMManager(self._fsm) + self._fsm.subscribe(self._fsm_updater.update) self.application = Application( [(r'/ws', ZMQWebSocketProxy, {'make_response': self.make_response, @@ -23,9 +26,13 @@ class TFWServer: def fsm(self): return self._fsm + @property + def fsm_manager(self): + return self._fsm_manager + def make_response(self, message): trigger = message.get('trigger', '') - try: self.fsm.trigger(trigger, message=message) + try: self._fsm_manager.trigger(trigger, message) except AttributeError: log.debug('FSM failed to execute nonexistent trigger: "{}"'.format(trigger)) return message @@ -36,6 +43,35 @@ class TFWServer: self.application.listen(port) +class FSMManager: + def __init__(self, fsm): + self._fsm = fsm + self.trigger_predicates = defaultdict(list) + self.messenge_sender = MessageSender() + + @property + def fsm(self): + return self._fsm + + def trigger(self, trigger, message): + predicate_results = [] + for predicate in self.trigger_predicates[trigger]: + success, message = predicate() + predicate_results.append(success) + self.messenge_sender.send('FSM', message) + + if all(predicate_results): + try: self.fsm.trigger(trigger, message=message) + except AttributeError: log.debug('FSM failed to execute nonexistent trigger: "{}"'.format(trigger)) + + def subscribe_predicate(self, trigger, *predicates): + self.trigger_predicates[trigger].extend(predicates) + + def unsubscribe_predicate(self, trigger, *predicates): + self.trigger_predicates[trigger] = [predicate for predicate in self.trigger_predicates[trigger] + not in predicates] + + class FSMUpdater: def __init__(self, fsm): self.fsm = fsm