Merge pull request #29 from avatao-content/fsmapi

Fsmapi
This commit is contained in:
Bokros Bálint 2018-04-11 15:33:46 +02:00 committed by GitHub
commit 5f48de037d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 15 deletions

View File

@ -7,6 +7,6 @@ from .fsm_base import FSMBase
class LinearFSM(FSMBase):
def __init__(self, number_of_steps):
self.states = list(map(str, range(number_of_steps)))
self.transitions = [{'trigger': 'step', 'source': index, 'dest': str(int(index)+1)}
self.transitions = [{'trigger': 'step_{}'.format(int(index)+1), 'source': index, 'dest': str(int(index)+1)}
for index in self.states[:-1]]
super(LinearFSM, self).__init__()

View File

@ -4,6 +4,27 @@
import json
def serialize_all(*args):
return tuple(_serialize_single(arg) for arg in args)
def deserialize_all(*args):
return tuple(_deserialize_single(arg) for arg in args)
def _serialize_single(data):
if not isinstance(data, str):
data = json.dumps(data)
return encode_if_needed(data)
def _deserialize_single(data):
try:
return json.loads(data)
except ValueError:
return decode_if_needed(data)
def encode_if_needed(value):
if isinstance(value, str):
value = value.encode('utf-8')
@ -14,11 +35,3 @@ def decode_if_needed(value):
if isinstance(value, (bytes, bytearray)):
value = value.decode('utf-8')
return value
def serialize_all(key, data):
return [encode_if_needed(frame) for frame in (key, json.dumps(data))]
def deserialize_all(key, data):
return decode_if_needed(key), json.loads(data)

View File

@ -25,6 +25,7 @@ class TFWServer:
self.application = Application(
[(r'/ws', ZMQWebSocketProxy, {'make_response': self.make_response,
'proxy_filter': self.proxy_filter,
'handle_trigger': self.handle_trigger,
'event_handler_connector': self._event_handler_connector})]
)
#self.controller_responder = ControllerResponder(self.fsm) TODO: add this once controller stuff is resolved
@ -38,13 +39,20 @@ class TFWServer:
return self._fsm_manager
def make_response(self, message):
self.trigger_fsm(message)
message['FSMUpdate'] = self._fsm_updater.get_fsm_state_and_transitions()
return message
def handle_trigger(self, message):
LOG.debug('Executing handler for trigger "%s"', message.get('trigger', ''))
self.trigger_fsm(message)
def trigger_fsm(self, message):
trigger = message.get('trigger', '')
try:
self._fsm_manager.trigger(trigger, message)
except AttributeError:
LOG.debug('FSM failed to execute nonexistent trigger: "%s"', trigger)
message['FSMUpdate'] = self._fsm_updater.get_fsm_state_and_transitions()
return message
def proxy_filter(self, message):
# pylint: disable=unused-argument,no-self-use

View File

@ -31,14 +31,15 @@ class ZMQWebSocketHandler(WebSocketHandler, ABC):
def zmq_callback(self, msg_parts):
keyhandlers = {'mirror': self.mirror}
key, data = deserialize_all(*msg_parts)
LOG.debug('Received on pull socket: %s', data)
key, message = deserialize_all(*msg_parts)
LOG.debug('Received on pull socket: %s', message)
self.handle_trigger(message)
if key not in keyhandlers:
for instance in ZMQWebSocketHandler.instances:
instance.write_message(data)
instance.write_message(message)
else:
try:
keyhandlers[key](data['data'])
keyhandlers[key](message['data'])
except KeyError:
LOG.error('Invalid mirror message format! Ignoring.')
@ -57,6 +58,10 @@ class ZMQWebSocketHandler(WebSocketHandler, ABC):
def send_message(self, message: dict, key: str = None):
self._event_handler_connector.send_message(message, key)
@abstractmethod
def handle_trigger(self, message):
raise NotImplementedError
# much secure, very cors, wow
def check_origin(self, origin):
return True
@ -68,6 +73,7 @@ class ZMQWebSocketProxy(ZMQWebSocketHandler):
super(ZMQWebSocketProxy, self).initialize(**kwargs)
self._make_response = kwargs['make_response']
self._proxy_filter = kwargs['proxy_filter']
self._handle_trigger = kwargs['handle_trigger']
def on_message(self, message):
message = json.loads(message)
@ -76,3 +82,6 @@ class ZMQWebSocketProxy(ZMQWebSocketHandler):
def make_response(self, message):
return self._make_response(message)
def handle_trigger(self, message):
self._handle_trigger(message)