Closed banjaxedben closed 3 years ago
Hello @banjaxedben,
calling model.trigger("event")
is equivalent to executing model.event()
. Both methods will only return after all callbacks have returned. If you have defined a 'machine.finalize_event', this will be executed before model.trigger
returns. I hope that the explanations added in 8186df0 improve the comprehension of this. I will close this issue for now as I consider this resolved. Feel free to comment anyway. I will reopen the issue if further actions need to be conducted.
Thanks for the clarification. I think the fundamental problem I have is that it is not clear how best to integrate my business logic with transitions. See my StackOverflow question here.
The transitions library gives the impression of being very simple, but there are traps for the unwary! I thought I could simply put my business logic in the on_enter callbacks, but I eventually learned that this was a bad idea: I must not trigger a state change from within a callback, and the code that calls a trigger method must be prepared to wait. Browsing old issues like #18, #30, #36, I get the sense that others have had a similar learning process as me. Could you distill the collective learning from these issues into something in the README? I am talking from the point of view of an engineer with no formal software training, so examples involving thread locks, asyncio, or coroutines tend to go over my head.
Hello @banjaxedben,
See my StackOverflow question here.
I just posted an answer. I hope this gives you some ideas about how to tackle that issue.
I must not trigger a state change from within a callback, and the code that calls a trigger method must be prepared to wait.
well, you can trigger a state change from within a callback. But callbacks need to return.
Could you distill the collective learning from these issues into something in the README?
I can give it a try but if you boil it down, you have a classic deadlock situation where pytransitions
is not part of the actual problem.
This:
def Model1:
success = False
def on_enter_FOO(self):
success = True
def Model2:
def on_enter_FOO(self):
while Model1.success is False:
time.sleep(1)
model1 = Model1()
model2 = Model2()
machine = Machine(model=[model1, model2], states=[''FOO'])
model2.to_FOO()
model1.to_FOO()
is a fancy way of writing:
success = False
def func1():
success = True
def func2():
while not success:
time.sleep(1)
func2()
func1()
I am talking from the point of view of an engineer with no formal software training, so examples involving thread locks, asyncio, or coroutines tend to go over my head.
Don't worry, this is tough for everyone.
I am using the
trigger()
method to execute transitions by name. I have found that thetrigger()
method does not return until the triggeredon_enter_<state>
callback completes. Referring to the callback execution order list here, where exactly does the trigger() method return?