Schedules a callback on the ``IOLoop`` when the given `.Future` is finished. The callback is invoked with one argument, the `.Future`. This method only accepts `.Future` objects and not other awaitables (unlike most of Tornado where the two are inter
(
self,
future: "Union[Future[_T], concurrent.futures.Future[_T]]",
callback: Callable[["Future[_T]"], None],
)
| 680 | self.add_callback(callback, *args, **kwargs) |
| 681 | |
| 682 | def add_future( |
| 683 | self, |
| 684 | future: "Union[Future[_T], concurrent.futures.Future[_T]]", |
| 685 | callback: Callable[["Future[_T]"], None], |
| 686 | ) -> None: |
| 687 | """Schedules a callback on the ``IOLoop`` when the given |
| 688 | `.Future` is finished. |
| 689 | |
| 690 | The callback is invoked with one argument, the |
| 691 | `.Future`. |
| 692 | |
| 693 | This method only accepts `.Future` objects and not other |
| 694 | awaitables (unlike most of Tornado where the two are |
| 695 | interchangeable). |
| 696 | """ |
| 697 | if isinstance(future, Future): |
| 698 | # Note that we specifically do not want the inline behavior of |
| 699 | # tornado.concurrent.future_add_done_callback. We always want |
| 700 | # this callback scheduled on the next IOLoop iteration (which |
| 701 | # asyncio.Future always does). |
| 702 | # |
| 703 | # Wrap the callback in self._run_callback so we control |
| 704 | # the error logging (i.e. it goes to tornado.log.app_log |
| 705 | # instead of asyncio's log). |
| 706 | future.add_done_callback( |
| 707 | lambda f: self._run_callback(functools.partial(callback, f)) |
| 708 | ) |
| 709 | else: |
| 710 | assert is_future(future) |
| 711 | # For concurrent futures, we use self.add_callback, so |
| 712 | # it's fine if future_add_done_callback inlines that call. |
| 713 | future_add_done_callback(future, lambda f: self.add_callback(callback, f)) |
| 714 | |
| 715 | def run_in_executor( |
| 716 | self, |