mirror of
https://github.com/avatao-content/baseimage-tutorial-framework
synced 2024-11-22 23:21:32 +00:00
Rework fsm_update API
This commit is contained in:
parent
d718b6425e
commit
a6b7fa04ab
@ -25,7 +25,7 @@ class FSMManagingEventHandler(EventHandlerBase):
|
|||||||
try:
|
try:
|
||||||
message = self.command_handlers[message['data']['command']](message)
|
message = self.command_handlers[message['data']['command']](message)
|
||||||
if message:
|
if message:
|
||||||
fsm_update_message = self._fsm_updater.generate_fsm_update()
|
fsm_update_message = self._fsm_updater.fsm_update
|
||||||
sign_message(self.auth_key, message)
|
sign_message(self.auth_key, message)
|
||||||
sign_message(self.auth_key, fsm_update_message)
|
sign_message(self.auth_key, fsm_update_message)
|
||||||
self.server_connector.broadcast(fsm_update_message)
|
self.server_connector.broadcast(fsm_update_message)
|
||||||
@ -52,23 +52,24 @@ class FSMUpdater:
|
|||||||
def __init__(self, fsm):
|
def __init__(self, fsm):
|
||||||
self.fsm = fsm
|
self.fsm = fsm
|
||||||
|
|
||||||
def generate_fsm_update(self):
|
@property
|
||||||
|
def fsm_update(self):
|
||||||
return {
|
return {
|
||||||
'key': 'fsm_update',
|
'key': 'fsm_update',
|
||||||
'data': self.get_fsm_state_and_transitions()
|
'data': self.fsm_update_data
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_fsm_state_and_transitions(self):
|
@property
|
||||||
state = self.fsm.state
|
def fsm_update_data(self):
|
||||||
valid_transitions = [
|
valid_transitions = [
|
||||||
{'trigger': trigger}
|
{'trigger': trigger}
|
||||||
for trigger in self.fsm.get_triggers(self.fsm.state)
|
for trigger in self.fsm.get_triggers(self.fsm.state)
|
||||||
]
|
]
|
||||||
last_trigger = self.fsm.trigger_history[-1] if self.fsm.trigger_history else None
|
last_fsm_event = self.fsm.event_log[-1]
|
||||||
in_accepted_state = state in self.fsm.accepted_states
|
last_fsm_event['timestamp'] = last_fsm_event['timestamp'].isoformat()
|
||||||
return {
|
return {
|
||||||
'current_state': state,
|
'current_state': self.fsm.state,
|
||||||
'valid_transitions': valid_transitions,
|
'valid_transitions': valid_transitions,
|
||||||
'last_trigger': last_trigger,
|
'in_accepted_state': self.fsm.in_accepted_state,
|
||||||
'in_accepted_state': in_accepted_state
|
'last_event': last_fsm_event
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ class EventHandlerBase(ABC):
|
|||||||
class FSMAware:
|
class FSMAware:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.fsm_state = None
|
self.fsm_state = None
|
||||||
self.in_accepted_state = False
|
self.fsm_in_accepted_state = False
|
||||||
self._auth_key = KeyManager().auth_key
|
self._auth_key = KeyManager().auth_key
|
||||||
|
|
||||||
def update_fsm_data(self, message):
|
def update_fsm_data(self, message):
|
||||||
@ -121,17 +121,18 @@ class FSMAware:
|
|||||||
def _handle_fsm_update(self, message):
|
def _handle_fsm_update(self, message):
|
||||||
try:
|
try:
|
||||||
new_state = message['data']['current_state']
|
new_state = message['data']['current_state']
|
||||||
trigger = message['data']['last_trigger']
|
|
||||||
if self.fsm_state != new_state:
|
if self.fsm_state != new_state:
|
||||||
self.handle_fsm_step(self.fsm_state, new_state, trigger)
|
self.handle_fsm_step(**(message['data']))
|
||||||
self.fsm_state = new_state
|
self.fsm_state = new_state
|
||||||
self.in_accepted_state = message['data']['in_accepted_state']
|
self.fsm_in_accepted_state = message['data']['in_accepted_state']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
LOG.error('Invalid fsm_update message received!')
|
LOG.error('Invalid fsm_update message received!')
|
||||||
|
|
||||||
def handle_fsm_step(self, from_state, to_state, trigger):
|
def handle_fsm_step(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Called in case the TFW FSM has stepped.
|
Called in case the TFW FSM has stepped.
|
||||||
|
|
||||||
|
:param kwargs: fsm_update 'data' field
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# All Rights Reserved. See LICENSE file for details.
|
# All Rights Reserved. See LICENSE file for details.
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from transitions import Machine, MachineError
|
from transitions import Machine, MachineError
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ class FSMBase(Machine, CallbackMixin):
|
|||||||
def __init__(self, initial=None, accepted_states=None):
|
def __init__(self, initial=None, accepted_states=None):
|
||||||
self.accepted_states = accepted_states or [self.states[-1].name]
|
self.accepted_states = accepted_states or [self.states[-1].name]
|
||||||
self.trigger_predicates = defaultdict(list)
|
self.trigger_predicates = defaultdict(list)
|
||||||
self.trigger_history = []
|
self.event_log = []
|
||||||
|
|
||||||
Machine.__init__(
|
Machine.__init__(
|
||||||
self,
|
self,
|
||||||
@ -60,9 +61,22 @@ class FSMBase(Machine, CallbackMixin):
|
|||||||
|
|
||||||
if all(predicate_results):
|
if all(predicate_results):
|
||||||
try:
|
try:
|
||||||
|
from_state = self.state
|
||||||
self.trigger(trigger)
|
self.trigger(trigger)
|
||||||
self.trigger_history.append(trigger)
|
self.update_event_log(from_state, trigger)
|
||||||
return True
|
return True
|
||||||
except (AttributeError, MachineError):
|
except (AttributeError, MachineError):
|
||||||
LOG.debug('FSM failed to execute nonexistent trigger: "%s"', trigger)
|
LOG.debug('FSM failed to execute nonexistent trigger: "%s"', trigger)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def update_event_log(self, from_state, trigger):
|
||||||
|
self.event_log.append({
|
||||||
|
'from_state': from_state,
|
||||||
|
'to_state': self.state,
|
||||||
|
'trigger': trigger,
|
||||||
|
'timestamp': datetime.utcnow()
|
||||||
|
})
|
||||||
|
|
||||||
|
@property
|
||||||
|
def in_accepted_state(self):
|
||||||
|
return self.state in self.accepted_states
|
||||||
|
Loading…
Reference in New Issue
Block a user