An iterator over the given futures that yields each as it completes. Args: fs: The sequence of Futures (possibly created by different Executors) to iterate over. timeout: The maximum number of seconds to wait. If None, then there is no limit on the wait t
(fs, timeout=None)
| 197 | |
| 198 | |
| 199 | def as_completed(fs, timeout=None): |
| 200 | """An iterator over the given futures that yields each as it completes. |
| 201 | |
| 202 | Args: |
| 203 | fs: The sequence of Futures (possibly created by different Executors) to |
| 204 | iterate over. |
| 205 | timeout: The maximum number of seconds to wait. If None, then there |
| 206 | is no limit on the wait time. |
| 207 | |
| 208 | Returns: |
| 209 | An iterator that yields the given Futures as they complete (finished or |
| 210 | cancelled). If any given Futures are duplicated, they will be returned |
| 211 | once. |
| 212 | |
| 213 | Raises: |
| 214 | TimeoutError: If the entire result iterator could not be generated |
| 215 | before the given timeout. |
| 216 | """ |
| 217 | if timeout is not None: |
| 218 | end_time = timeout + time.monotonic() |
| 219 | |
| 220 | fs = set(fs) |
| 221 | total_futures = len(fs) |
| 222 | with _AcquireFutures(fs): |
| 223 | finished = set( |
| 224 | f for f in fs |
| 225 | if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]) |
| 226 | pending = fs - finished |
| 227 | waiter = _create_and_install_waiters(fs, _AS_COMPLETED) |
| 228 | finished = list(finished) |
| 229 | try: |
| 230 | yield from _yield_finished_futures(finished, waiter, |
| 231 | ref_collect=(fs,)) |
| 232 | |
| 233 | while pending: |
| 234 | if timeout is None: |
| 235 | wait_timeout = None |
| 236 | else: |
| 237 | wait_timeout = end_time - time.monotonic() |
| 238 | if wait_timeout < 0: |
| 239 | raise TimeoutError( |
| 240 | '%d (of %d) futures unfinished' % ( |
| 241 | len(pending), total_futures)) |
| 242 | |
| 243 | waiter.event.wait(wait_timeout) |
| 244 | |
| 245 | with waiter.lock: |
| 246 | finished = waiter.finished_futures |
| 247 | waiter.finished_futures = [] |
| 248 | waiter.event.clear() |
| 249 | |
| 250 | # reverse to keep finishing order |
| 251 | finished.reverse() |
| 252 | yield from _yield_finished_futures(finished, waiter, |
| 253 | ref_collect=(fs, pending)) |
| 254 | |
| 255 | finally: |
| 256 | # Remove waiter from unfinished futures |
nothing calls this directly
no test coverage detected