Chain two futures together so that when one completes, so does the other. The result (success or failure) of ``a`` will be copied to ``b``, unless ``b`` has already been completed or cancelled by the time ``a`` finishes. .. versionchanged:: 5.0 Now accepts both Tornado/asyncio
(a: "Future[_T]", b: "Future[_T]")
| 139 | |
| 140 | |
| 141 | def chain_future(a: "Future[_T]", b: "Future[_T]") -> None: |
| 142 | """Chain two futures together so that when one completes, so does the other. |
| 143 | |
| 144 | The result (success or failure) of ``a`` will be copied to ``b``, unless |
| 145 | ``b`` has already been completed or cancelled by the time ``a`` finishes. |
| 146 | |
| 147 | .. versionchanged:: 5.0 |
| 148 | |
| 149 | Now accepts both Tornado/asyncio `Future` objects and |
| 150 | `concurrent.futures.Future`. |
| 151 | |
| 152 | """ |
| 153 | |
| 154 | def copy(future: "Future[_T]") -> None: |
| 155 | assert future is a |
| 156 | if b.done(): |
| 157 | return |
| 158 | if hasattr(a, "exc_info") and a.exc_info() is not None: # type: ignore |
| 159 | future_set_exc_info(b, a.exc_info()) # type: ignore |
| 160 | elif a.exception() is not None: |
| 161 | b.set_exception(a.exception()) |
| 162 | else: |
| 163 | b.set_result(a.result()) |
| 164 | |
| 165 | if isinstance(a, Future): |
| 166 | future_add_done_callback(a, copy) |
| 167 | else: |
| 168 | # concurrent.futures.Future |
| 169 | from tornado.ioloop import IOLoop |
| 170 | |
| 171 | IOLoop.current().add_future(a, copy) |
| 172 | |
| 173 | |
| 174 | def future_set_result_unless_cancelled( |
no test coverage detected