Runs a function in a ``concurrent.futures.Executor``. If ``executor`` is ``None``, the IO loop's default executor will be used. Use `functools.partial` to pass keyword arguments to ``func``. .. versionadded:: 5.0
(
self,
executor: Optional[concurrent.futures.Executor],
func: Callable[..., _T],
*args: Any,
)
| 713 | future_add_done_callback(future, lambda f: self.add_callback(callback, f)) |
| 714 | |
| 715 | def run_in_executor( |
| 716 | self, |
| 717 | executor: Optional[concurrent.futures.Executor], |
| 718 | func: Callable[..., _T], |
| 719 | *args: Any, |
| 720 | ) -> "Future[_T]": |
| 721 | """Runs a function in a ``concurrent.futures.Executor``. If |
| 722 | ``executor`` is ``None``, the IO loop's default executor will be used. |
| 723 | |
| 724 | Use `functools.partial` to pass keyword arguments to ``func``. |
| 725 | |
| 726 | .. versionadded:: 5.0 |
| 727 | """ |
| 728 | if executor is None: |
| 729 | if not hasattr(self, "_executor"): |
| 730 | from tornado.process import cpu_count |
| 731 | |
| 732 | self._executor = concurrent.futures.ThreadPoolExecutor( |
| 733 | max_workers=(cpu_count() * 5) |
| 734 | ) # type: concurrent.futures.Executor |
| 735 | executor = self._executor |
| 736 | c_future = executor.submit(func, *args) |
| 737 | # Concurrent Futures are not usable with await. Wrap this in a |
| 738 | # Tornado Future instead, using self.add_future for thread-safety. |
| 739 | t_future = Future() # type: Future[_T] |
| 740 | self.add_future(c_future, lambda f: chain_future(f, t_future)) |
| 741 | return t_future |
| 742 | |
| 743 | def set_default_executor(self, executor: concurrent.futures.Executor) -> None: |
| 744 | """Sets the default executor to use with :meth:`run_in_executor`. |
no test coverage detected