Skip to content

Commit

Permalink
status: do not create thread to run callbacks if timeout is None
Browse files Browse the repository at this point in the history
  • Loading branch information
Mathias Guijarro committed Mar 21, 2024
1 parent 264e3df commit 61745f3
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
27 changes: 22 additions & 5 deletions ophyd/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,13 @@ def __init__(self, *, timeout=None, settle_time=0, done=None, success=None):
DeprecationWarning,
)

self._callback_thread = threading.Thread(
target=self._run_callbacks, daemon=True, name=self._tname
)
self._callback_thread.start()
if timeout is None:
self._callback_thread = None
else:
self._callback_thread = threading.Thread(
target=self._run_callbacks, daemon=True, name=self._tname
)
self._callback_thread.start()

if done:
if success:
Expand Down Expand Up @@ -326,6 +329,9 @@ def set_exception(self, exc):
self._exception = exc
self._settled_event.set()

if self._callback_thread is None:
self._run_callbacks()

def set_finished(self):
"""
Mark as finished successfully.
Expand All @@ -344,10 +350,21 @@ def set_finished(self):
# same thread. This just sets an Event, either from this thread (the
# one calling set_finished) or the thread created below.
if self.settle_time > 0:
threading.Timer(self.settle_time, self._settled_event.set).start()
if self._callback_thread is None:

def settle_done():
self._settled_event.set()
self._run_callbacks()

threading.Timer(self.settle_time, settle_done).start()
else:
threading.Timer(self.settle_time, self._settled_event.set).start()
else:
self._settled_event.set()

if self._callback_thread is None:
self._run_callbacks()

def _finished(self, success=True, **kwargs):
"""
Inform the status object that it is done and if it succeeded.
Expand Down
21 changes: 21 additions & 0 deletions ophyd/tests/test_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,27 @@ def test_status_timeout_with_settle_time():
st.wait(2)


def test_status_timeout_infinite_with_settle_time():
"""
A StatusTimeoutError is raised when the timeout set in __init__ plus the
settle_time has expired.
"""
cb = Mock()
st = StatusBase(settle_time=1)
st.add_callback(cb)

# there is no timeout, explicitely set finished ;
# the callback should be called after "settle_time"
st.set_finished()

assert cb.call_count == 0
with pytest.raises(WaitTimeoutError):
# not ready yet
st.wait(0.5)
st.wait(0.6)
cb.assert_called_once()


def test_external_timeout():
"""
A TimeoutError is raised, not StatusTimeoutError or WaitTimeoutError,
Expand Down

0 comments on commit 61745f3

Please sign in to comment.