我正在为我的 FSM 使用 python 转换,它非常适合顺序事件和最近添加的超时功能。我的代码完全是基于 txdbus(基于 Twisted 的 dbus 事件)的异步代码,其中我对系统或硬件中的任何异步事件使用 defer,并且代码在反应器循环中运行。
现在,如果我开始转换状态并根据条件,它会调用一个在未来给出 TRUE/False 的函数(最初返回延迟,但实际上运行一个异步调用,如等待文件下载,并以成功/失败返回以后下载文件)
在这种情况下,如何仅当反应堆循环中的异步函数返回时才维护状态机并转换到下一个状态。 (我尝试在函数回调后设置状态,但它不起作用)
任何人都使用过 FSM 转换,并且扭曲(或者我让事情变得复杂:))
我认为将有限状态机 (FSM) 的转换模块与基于 Twisted (txdbus) 的异步系统集成可能具有挑战性。这是让 FSM 处理异步操作的一种方法:
回调和延迟: 当异步函数返回 Deferred 时,您应该在该 Deferred 的回调中触发到新状态的转换。这确保了状态转换仅在异步事件完成时发生。
转换和异步操作: 定义转换以启动异步操作并仅在该操作成功时更改状态。
实施: 这是一个示例来说明它的外观:
from transitions import Machine
from twisted.internet import reactor, defer
class MyStateMachine(object):
states = ['state1', 'state2', 'state3']
def __init__(self):
self.machine = Machine(model=self, states=MyStateMachine.states, initial='state1')
self.machine.add_transition(trigger='to_state2', source='state1', dest='state2', before='start_async_operation')
self.machine.add_transition(trigger='to_state3', source='state2', dest='state3')
def start_async_operation(self):
d = self.async_function()
d.addCallback(self.on_async_success)
d.addErrback(self.on_async_failure)
def async_function(self):
# Example of an asynchronous function returning a Deferred
d = defer.Deferred()
reactor.callLater(2, d.callback, True) # Simulates an asynchronous operation
return d
def on_async_success(self, result):
if result:
self.to_state3()
else:
print("Async operation failed")
def on_async_failure(self, failure):
print("Error in async operation:", failure)
fsm = MyStateMachine()
print(fsm.state) # Output: state1
fsm.to_state2()
reactor.run()
start_async_operation 在转换到 state2 之前被调用。 async_function 方法模拟异步操作并返回 Deferred。 如果异步操作成功(on_async_success),则触发下一个状态转换(to_state3)。 如果异步操作出现错误(on_async_failure),则会打印错误消息。
确保状态转换和异步操作明确分开。 使用 Deferred 对象监视异步操作的完成情况并触发适当的状态转换。 避免异步函数内直接改变状态;使用回调和错误返回来代替。