I have one task that I want to do:
def task(body):
# some logic that which can throw an exception
# if something goes wrong
do_task(body)
and the logic inside this task can throw an exception
And I have execute method with executor:
def execute():
executor = ThreadPoolExecutor(max_workers=4)
future1 = executor.submit(task, body1)
future2 = executor.submit(task, body2)
future3 = executor.submit(task, body3)
future4 = executor.submit(task, body4)
result1 = future1.result()
result2 = future2.result()
result3 = future3.result()
result4 = future4.result()
And I want if at least one task crashes - do not wait for the completion of other tasks and stopped everything. How can I do this correctly?
To abandon waiting for other tasks when one raises, you can use concurrent.futures.wait()
with the FIRST_EXCEPTION
flag:
def execute():
executor = ThreadPoolExecutor(max_workers=4)
future1 = executor.submit(task, body1)
future2 = executor.submit(task, body2)
future3 = executor.submit(task, body3)
future4 = executor.submit(task, body4)
done, not_done = concurrent.futures.wait(
[future1, future2, future3, future4],
return_when=concurrent.futures.FIRST_EXCEPTION
)
if not_done:
# at least one future has raised - you can return here
# or propagate the exception
#list(not_done)[0].result() # re-raises exception here
return # ignores exception and returns
result1 = future1.result()
result2 = future2.result()
result3 = future3.result()
result4 = future4.result()
...
Note that the remaining tasks will still keep running in the background. There is no way to stop them forcibly.