The documentation around timeouts for concurrent.futures is very challenging to understand. In a simple case, I'd like to use a ProcessPoolExecutor by calling .submit in a loop that scans through a list of job functions. I want each of these Future objects to have an associated timeout of 10 minutes, but otherwise for them to complete asynchronously.
My first approach was to try to use the as_completed function, which produces an iterator of the Future objects and only yields the next when one has completed. as_completed accepts a timeout parameter but the documentation says this timeout is relative to the first moment when as_completed is called, and not necessarily the lifetime of any Future object itself.
E.g. suppose the ProcessPoolExecutor only has 3 worker processes but the list of Future objects contains 10 items. 7 of the items may sit in an unprocessed state for up to 10 minutes while the first 3 items are processed. Shortly thereafter, the timeout from as_completed will be tripped resulting in a failure, even though each individual Future may have met the 10 minute limit on its own.
Note that the same limitations that apply for as_completed will also apply for wait and wait is harder to use for this use case because of the limited return options it supports.
My next thought was to use the timeout parameter that future.result allows and call f.result(timeout=600) for each f (Future) in my list of futures. However, there is not really a way to set this timeout without actually demanding the result in a blocking way. If you iterate the list of futures and call f.result(...), this call blocks for the specified timeout.
On the other hand, you also cannot combine f.result with as_completed either, in a naive but seemingly correct way like
[f.result(timeout=600) for f in as_completed(futures_list)]
... because the iteration of as_completed is deceptively waiting asynchronously as the futures complete and only returning them to have .result called after they have already completed.
Given this, what is the right pattern to produce a list of Futures where each one has its own individual timeout and then wait on them asynchronously to finish?