At the point an executor has been shutdown, its state has already been set:
_stopped is True
_result_watcher is gone (None)
_task_submitter is (nominally) stopped
In refactoring for idempotency (early return), realize that there is no use to .join() the task submitter thread. The Python internals already clean up the underlying thread when the thread completes. All .join() does is wait for that -- there is no resource value in waiting, only algorithm logic, if necessary. Instead, take out the shutdown lock and drain the queue of tasks before sending the poison pill, then stop there. The thread will either complete or it won't, but because it's daemon=True, it won't hold up the shutdown process.
At the point an executor has been shutdown, its state has already been set:
_stopped
isTrue
_result_watcher
is gone (None
)_task_submitter
is (nominally) stoppedIn refactoring for idempotency (early return), realize that there is no use to
.join()
the task submitter thread. The Python internals already clean up the underlying thread when the thread completes. All.join()
does is wait for that -- there is no resource value in waiting, only algorithm logic, if necessary. Instead, take out the shutdown lock and drain the queue of tasks before sending the poison pill, then stop there. The thread will either complete or it won't, but because it'sdaemon=True
, it won't hold up the shutdown process.[sc-33249]
Type of change