added optional 'block_on_transition' param for 'ensure' function that's called while a transition is in-process
This commit is contained in:
parent
661cdd2018
commit
7968ca2892
@ -91,7 +91,6 @@ class StateMachine(object):
|
|||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
try: # lock is acquired; all other threads will return false or wait until notify/timeout
|
try: # lock is acquired; all other threads will return false or wait until notify/timeout
|
||||||
self.notifier.clear()
|
|
||||||
if self.__current_state in from_states: # should always be True due to lock
|
if self.__current_state in from_states: # should always be True due to lock
|
||||||
|
|
||||||
# Note that func might throw an exception, but that's OK, it aborts the transition
|
# Note that func might throw an exception, but that's OK, it aborts the transition
|
||||||
@ -108,7 +107,8 @@ class StateMachine(object):
|
|||||||
log.error( "StateMachine bug!! The lock should ensure this doesn't happen!" )
|
log.error( "StateMachine bug!! The lock should ensure this doesn't happen!" )
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
self.notifier.set()
|
self.notifier.set() # notify any waiting threads that the state has changed.
|
||||||
|
self.notifier.clear()
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ class StateMachine(object):
|
|||||||
return self.ensure_any( (state,), wait=wait )
|
return self.ensure_any( (state,), wait=wait )
|
||||||
|
|
||||||
|
|
||||||
def ensure_any(self, states, wait=0.0):
|
def ensure_any(self, states, wait=0.0, block_on_transition=False):
|
||||||
'''
|
'''
|
||||||
Ensure we are currently in one of the given `states` or wait until
|
Ensure we are currently in one of the given `states` or wait until
|
||||||
we enter one of those states.
|
we enter one of those states.
|
||||||
@ -173,11 +173,15 @@ class StateMachine(object):
|
|||||||
if not state in self.__states:
|
if not state in self.__states:
|
||||||
raise ValueError( "StateMachine does not contain state '%s'" % state )
|
raise ValueError( "StateMachine does not contain state '%s'" % state )
|
||||||
|
|
||||||
# Locking never really gained us anything here, since the lock was released
|
# if we're in the middle of a transition, determine whether we should
|
||||||
# before the function returned anyways. The only thing it _did_ do was
|
# 'fall back' to the 'current' state, or wait for the new state, in order to
|
||||||
# increase the probability that this function would block for longer than
|
# avoid an operation occurring in the wrong state.
|
||||||
# intended if a `transition` function or context was running while holding
|
# TODO another option would be an ensure_ctx that uses a semaphore to allow
|
||||||
# the lock.
|
# threads to indicate they want to remain in a particular state.
|
||||||
|
|
||||||
|
# will return immediately if no transition is in process.
|
||||||
|
if block_on_transition: self.notifier.wait()
|
||||||
|
|
||||||
start = time.time()
|
start = time.time()
|
||||||
while not self.__current_state in states:
|
while not self.__current_state in states:
|
||||||
# detect timeout:
|
# detect timeout:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user